this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

more

+1625 -1083
+57 -23
stack/jmap/CLAUDE.md
··· 28 28 ### ✅ Good - Using the typed JMAP library API: 29 29 ```ocaml 30 30 (* Build Email/query request using typed constructors *) 31 - let query_request = Jmap_mail.Jmap_email.Query.request_v 32 - ~account_id:(Jmap_core.Jmap_id.of_string account_id) 33 - ~limit:(Jmap_core.Jmap_primitives.UnsignedInt.of_int 10) 34 - ~sort:[Jmap_core.Jmap_comparator.v ~property:"receivedAt" ~is_ascending:false ()] 31 + let query_request = Jmap_mail.Email.Query.request_v 32 + ~account_id:(Jmap_core.Id.of_string account_id) 33 + ~limit:(Jmap_core.Primitives.UnsignedInt.of_int 10) 34 + ~sort:[Jmap_core.Comparator.v ~property:"receivedAt" ~is_ascending:false ()] 35 35 ~calculate_total:true 36 36 () in 37 37 38 38 (* Convert to JSON *) 39 - let query_args = Jmap_mail.Jmap_email.Query.request_to_json query_request in 39 + let query_args = Jmap_mail.Email.Query.request_to_json query_request in 40 40 41 41 (* Create invocation using Echo witness *) 42 - let query_invocation = Jmap_core.Jmap_invocation.Invocation { 42 + let query_invocation = Jmap_core.Invocation.Invocation { 43 43 method_name = "Email/query"; 44 44 arguments = query_args; 45 45 call_id = "q1"; 46 - witness = Jmap_core.Jmap_invocation.Echo; 46 + witness = Jmap_core.Invocation.Echo; 47 47 } in 48 48 49 49 (* Build request using constructors *) 50 - let req = Jmap_core.Jmap_request.make 51 - ~using:[Jmap_core.Jmap_capability.core; Jmap_core.Jmap_capability.mail] 52 - [Jmap_core.Jmap_invocation.Packed query_invocation] 50 + let req = Jmap_core.Request.make 51 + ~using:[Jmap_core.Capability.core; Jmap_core.Capability.mail] 52 + [Jmap_core.Invocation.Packed query_invocation] 53 53 in 54 54 55 55 (* Make the call *) 56 56 let query_resp = Jmap_client.call client req in 57 57 58 58 (* Extract results using type-safe response_to_json *) 59 - let method_responses = Jmap_core.Jmap_response.method_responses query_resp in 59 + let method_responses = Jmap_core.Response.method_responses query_resp in 60 60 match method_responses with 61 61 | [packed_resp] -> 62 - let response_json = Jmap_core.Jmap_invocation.response_to_json packed_resp in 62 + let response_json = Jmap_core.Invocation.response_to_json packed_resp in 63 63 (* Now parse response_json... *) 64 64 (match response_json with 65 65 | `O fields -> ··· 70 70 | _ -> failwith "Unexpected response" 71 71 ``` 72 72 73 + **Using the unified Jmap module (recommended)**: 74 + ```ocaml 75 + (* Even cleaner with the unified Jmap module *) 76 + let query_request = Jmap.Email.Query.request_v 77 + ~account_id:(Jmap.Id.of_string account_id) 78 + ~limit:(Jmap.Primitives.UnsignedInt.of_int 10) 79 + ~sort:[Jmap.Comparator.v ~property:"receivedAt" ~is_ascending:false ()] 80 + ~calculate_total:true 81 + () in 82 + 83 + let query_args = Jmap.Email.Query.request_to_json query_request in 84 + let query_invocation = Jmap.Invocation.Invocation { 85 + method_name = "Email/query"; 86 + arguments = query_args; 87 + call_id = "q1"; 88 + witness = Jmap.Invocation.Echo; 89 + } in 90 + 91 + let req = Jmap.Request.make 92 + ~using:[Jmap.Capability.core; Jmap.Capability.mail] 93 + [Jmap.Invocation.Packed query_invocation] 94 + in 95 + 96 + let query_resp = Jmap.Client.call client req in 97 + 98 + let method_responses = Jmap.Response.method_responses query_resp in 99 + match method_responses with 100 + | [packed_resp] -> 101 + let response_json = Jmap.Invocation.response_to_json packed_resp in 102 + (* process response... *) 103 + | _ -> failwith "Unexpected response" 104 + ``` 105 + 73 106 The key principles: 74 107 1. Use typed `request_v` constructors (e.g., `Email.Query.request_v`, `Email.Get.request_v`) 75 108 2. Convert typed requests to JSON with `request_to_json` 76 - 3. Wrap in invocations and build JMAP requests with `Jmap_request.make` 77 - 4. Use `Jmap_invocation.response_to_json` to safely extract response data from packed responses 109 + 3. Wrap in invocations and build JMAP requests with `Request.make` 110 + 4. Use `Invocation.response_to_json` to safely extract response data from packed responses 78 111 79 112 ## Architecture 80 113 114 + - **jmap**: Unified ergonomic interface (recommended for most users) 81 115 - **jmap-core**: Core JMAP types (Session, Request, Response, Invocations, Standard Methods) 82 116 - **jmap-mail**: Email-specific types (RFC 8621) 83 117 - **jmap-client**: HTTP client implementation using Eio and the Requests library 84 118 85 119 ## Key Modules 86 120 87 - ### Jmap_request 88 - Build JMAP requests using `Jmap_request.make`: 121 + ### Jmap.Request (or Jmap_core.Request) 122 + Build JMAP requests using `Request.make`: 89 123 ```ocaml 90 124 val make : 91 - ?created_ids:(Jmap_id.t * Jmap_id.t) list option -> 92 - using:Jmap_capability.t list -> 93 - Jmap_invocation.invocation_list -> 125 + ?created_ids:(Id.t * Id.t) list option -> 126 + using:Capability.t list -> 127 + Invocation.invocation_list -> 94 128 t 95 129 ``` 96 130 97 - ### Jmap_invocation 131 + ### Jmap.Invocation (or Jmap_core.Invocation) 98 132 Type-safe method invocations using GADT witnesses: 99 133 ```ocaml 100 134 type ('args, 'resp) method_witness = ··· 106 140 107 141 For generic JSON methods, use the Echo witness. For typed methods, use the appropriate witness. 108 142 109 - ### Jmap_capability 143 + ### Jmap.Capability (or Jmap_core.Capability) 110 144 Use predefined capability constants: 111 145 ```ocaml 112 - let caps = [Jmap_capability.core; Jmap_capability.mail] 146 + let caps = [Jmap.Capability.core; Jmap.Capability.mail] 113 147 ``` 114 148 115 149 Or create from URN strings: 116 150 ```ocaml 117 - let cap = Jmap_capability.of_string "urn:ietf:params:jmap:core" 151 + let cap = Jmap.Capability.of_string "urn:ietf:params:jmap:core" 118 152 ``` 119 153 120 154 ## Testing Against Real Servers
+43 -33
stack/jmap/README.md
··· 1 1 # JMAP Implementation 2 2 3 - OCaml implementation of the JMAP protocol (RFC 8620) with Eio for async I/O. 3 + OCaml implementation of the JMAP protocol (RFC 8620, RFC 8621) with Eio for async I/O. 4 4 5 - ## Structure 5 + ## Packages 6 6 7 - - **jmap-core**: Core JMAP protocol types and parsers 7 + - **jmap**: Unified, ergonomic interface combining all libraries (recommended) 8 + - **jmap-core**: Core JMAP protocol types and parsers (RFC 8620) 8 9 - **jmap-mail**: JMAP Mail extension (RFC 8621) 9 10 - **jmap-client**: HTTP client for JMAP servers using Eio 10 11 11 12 ## Features 12 13 14 + - ✅ **Ergonomic API**: Clean, unified `Jmap` module with short aliases 15 + - ✅ **Type-safe**: Uses GADTs to ensure compile-time correctness 13 16 - ✅ Full Eio-based async I/O 14 17 - ✅ Uses `Requests` library for HTTP client layer 15 18 - ✅ Bearer token and Basic authentication ··· 17 20 - ✅ API calls with proper JSON serialization 18 21 - ✅ Upload and download support 19 22 20 - ## Usage 23 + ## Installation 24 + 25 + ```bash 26 + # Recommended: Install the unified package 27 + opam install jmap 21 28 22 - ### Creating a Client 29 + # Or install individual packages for specialized use 30 + opam install jmap-core jmap-mail jmap-client 31 + ``` 32 + 33 + ## Quick Start 34 + 35 + ### Using the Unified API (Recommended) 23 36 24 37 ```ocaml 25 38 Eio_main.run @@ fun env -> 26 39 Eio.Switch.run @@ fun sw -> 27 40 28 41 (* Create connection with authentication *) 29 - let conn = Jmap_connection.v 30 - ~auth:(Jmap_connection.Bearer "your-api-token") 31 - () in 42 + let conn = Jmap.Connection.bearer_auth ~token:"your-api-token" () in 32 43 33 44 (* Create client *) 34 - let client = Jmap_client.create 45 + let client = Jmap.Client.create 35 46 ~sw 36 47 ~env 37 48 ~conn ··· 39 50 () in 40 51 41 52 (* Fetch session *) 42 - let session = Jmap_client.fetch_session client in 43 - Printf.printf "Username: %s\n" (Jmap_core.Jmap_session.username session); 44 - ``` 53 + let session = Jmap.Client.get_session client in 54 + Printf.printf "Username: %s\n" (Jmap.Session.username session); 45 55 46 - ### Making API Calls 56 + (* Query emails using typed API *) 57 + let query_req = Jmap.Email.Query.request_v 58 + ~account_id:(Jmap.Id.of_string account_id) 59 + ~limit:(Jmap.Primitives.UnsignedInt.of_int 10) 60 + () 61 + in 47 62 48 - ```ocaml 49 - (* Build a JMAP request *) 50 - let request_json = \`O [ 51 - ("using", \`A [\`String "urn:ietf:params:jmap:core"; \`String "urn:ietf:params:jmap:mail"]); 52 - ("methodCalls", \`A [ 53 - \`A [ 54 - \`String "Email/query"; 55 - \`O [("accountId", \`String account_id); ("limit", \`Float 10.)]; 56 - \`String "c1" 57 - ] 58 - ]) 59 - ] in 63 + let query_args = Jmap.Email.Query.request_to_json query_req in 64 + let invocation = Jmap.Invocation.make_echo "Email/query" query_args "q1" in 65 + let req = Jmap.Request.make 66 + ~using:[Jmap.Capability.core; Jmap.Capability.mail] 67 + [invocation] 68 + in 60 69 61 - let req = Jmap_core.Jmap_request.Parser.of_json request_json in 62 - let resp = Jmap_client.call client req in 70 + let resp = Jmap.Client.call client req 63 71 ``` 72 + 73 + For more examples and advanced usage, see [USAGE_GUIDE.md](USAGE_GUIDE.md). 64 74 65 75 ## Testing with Fastmail 66 76 ··· 76 86 dune exec jmap/test/test_fastmail.exe 77 87 ``` 78 88 79 - ## Migration from Unix to Eio 89 + ## Architecture 80 90 81 - The JMAP client has been migrated from Unix-based I/O to Eio: 91 + The library is organized into clean, modular packages: 82 92 83 - - ✅ Replaced blocking I/O with Eio structured concurrency 84 - - ✅ Integrated with `Requests` library for HTTP 85 - - ✅ Added proper resource management with switches 86 - - ✅ Maintained backward-compatible API where possible 93 + - ✅ Unified `Jmap` module for ergonomic, everyday use 94 + - ✅ Specialized submodules (`Jmap_core`, `Jmap_mail`) for advanced cases 95 + - ✅ Full Eio integration with structured concurrency 96 + - ✅ Type-safe GADTs for compile-time correctness 87 97 88 98 ## Dependencies 89 99
+169
stack/jmap/USAGE_GUIDE.md
··· 1 + # JMAP Library Usage Guide 2 + 3 + ## Ergonomic API Design 4 + 5 + The JMAP library provides a clean, ergonomic API with short module names and a unified entry point. 6 + 7 + ## Module Structure 8 + 9 + ### Unified `Jmap` Module (Recommended) 10 + 11 + The unified `Jmap` module combines `jmap-core`, `jmap-mail`, and `jmap-client` into a single, easy-to-use interface. 12 + 13 + ```ocaml 14 + let id = Jmap.Id.of_string "abc123" 15 + let email_req = Jmap.Email.Query.request_v ~account_id ... 16 + let client = Jmap.Client.create ... 17 + ``` 18 + 19 + ### Submodules (For Specialized Use) 20 + 21 + You can also use the submodules directly: 22 + 23 + **Jmap_core**: 24 + ```ocaml 25 + Jmap_core.Session.t 26 + Jmap_core.Id.of_string 27 + Jmap_core.Request.make 28 + ``` 29 + 30 + **Jmap_mail**: 31 + ```ocaml 32 + Jmap_mail.Email.Query.request_v 33 + Jmap_mail.Mailbox.get 34 + ``` 35 + 36 + ## Module Hierarchy 37 + 38 + ### High-Level API (Recommended for Most Users) 39 + 40 + ``` 41 + Jmap -- Unified interface (START HERE) 42 + ├── Client -- HTTP client (from jmap-client) 43 + ├── Connection -- Connection config (from jmap-client) 44 + 45 + ├── Email -- Email operations (from jmap-mail) 46 + ├── Mailbox -- Mailbox operations (from jmap-mail) 47 + ├── Thread -- Thread operations (from jmap-mail) 48 + ├── Identity -- Identity management (from jmap-mail) 49 + ├── Email_submission -- Email submission (from jmap-mail) 50 + ├── Vacation_response -- Vacation responses (from jmap-mail) 51 + ├── Search_snippet -- Search snippets (from jmap-mail) 52 + 53 + ├── Session -- JMAP Session (from jmap-core) 54 + ├── Request -- Request building (from jmap-core) 55 + ├── Response -- Response handling (from jmap-core) 56 + ├── Invocation -- Method invocations (from jmap-core) 57 + ├── Id -- JMAP IDs (from jmap-core) 58 + ├── Capability -- Capabilities (from jmap-core) 59 + ├── Filter -- Filters (from jmap-core) 60 + ├── Comparator -- Sorting (from jmap-core) 61 + ├── Primitives -- Primitive types (from jmap-core) 62 + ├── Error -- Error handling (from jmap-core) 63 + ├── Binary -- Upload/download (from jmap-core) 64 + ├── Push -- Push notifications (from jmap-core) 65 + 66 + ├── Core -- Full jmap-core access 67 + └── Mail -- Full jmap-mail access 68 + ``` 69 + 70 + ### Specialized APIs (For Advanced Use Cases) 71 + 72 + ``` 73 + Jmap_core -- Core protocol library 74 + ├── Session 75 + ├── Id 76 + ├── Request 77 + ├── Response 78 + └── ... 79 + 80 + Jmap_mail -- Mail extension library 81 + ├── Email 82 + ├── Mailbox 83 + ├── Thread 84 + └── ... 85 + 86 + Jmap_client -- HTTP client library 87 + └── (unwrapped: Jmap_client, Jmap_connection) 88 + ``` 89 + 90 + ## Usage Examples 91 + 92 + ### Example 1: Creating a Client and Querying Emails 93 + 94 + ```ocaml 95 + let conn = Jmap.Connection.bearer_auth ~token:"..." () in 96 + let client = Jmap.Client.create ~sw ~env ~conn ~session_url:"..." () in 97 + let session = Jmap.Client.get_session client in 98 + 99 + let query_req = Jmap.Email.Query.request_v 100 + ~account_id:(Jmap.Id.of_string account_id) 101 + ~limit:(Jmap.Primitives.UnsignedInt.of_int 10) 102 + ~sort:[Jmap.Comparator.v ~property:"receivedAt" ~is_ascending:false ()] 103 + () 104 + in 105 + 106 + let query_args = Jmap.Email.Query.request_to_json query_req in 107 + let invocation = Jmap.Invocation.Invocation { 108 + method_name = "Email/query"; 109 + arguments = query_args; 110 + call_id = "q1"; 111 + witness = Jmap.Invocation.Echo; 112 + } in 113 + 114 + let req = Jmap.Request.make 115 + ~using:[Jmap.Capability.core; Jmap.Capability.mail] 116 + [Jmap.Invocation.Packed invocation] 117 + in 118 + 119 + let resp = Jmap.Client.call client req in 120 + ``` 121 + 122 + ### Example 2: Using Submodules 123 + 124 + ```ocaml 125 + (* Use Jmap_core for core protocol operations *) 126 + let session = Jmap_core.Session.of_json json in 127 + let account_id = Jmap_core.Id.of_string "abc123" in 128 + 129 + (* Use Jmap_mail for mail-specific operations *) 130 + let email_req = Jmap_mail.Email.Query.request_v 131 + ~account_id 132 + ~limit:(Jmap_core.Primitives.UnsignedInt.of_int 50) 133 + () 134 + in 135 + ``` 136 + 137 + ### Example 3: Working with IDs and Primitives 138 + 139 + ```ocaml 140 + let account_id = Jmap.Id.of_string "abc123" in 141 + let limit = Jmap.Primitives.UnsignedInt.of_int 50 in 142 + let id_str = Jmap.Id.to_string account_id in 143 + ``` 144 + 145 + ## Package Structure 146 + 147 + - **`jmap`** - Unified interface (recommended for applications) 148 + - **`jmap-core`** - Core protocol (RFC 8620) 149 + - **`jmap-mail`** - Mail extension (RFC 8621) 150 + - **`jmap-client`** - HTTP client implementation 151 + - **`jmap-test`** - Test suite 152 + 153 + Most users should depend on `jmap`, which pulls in all three libraries. For specialized use cases (e.g., you only need parsing), you can depend on individual packages. 154 + 155 + ## Quick Reference 156 + 157 + | Use Case | Unified API | Submodule API | 158 + |----------|-------------|---------------| 159 + | IDs | `Jmap.Id` | `Jmap_core.Id` | 160 + | Requests | `Jmap.Request` | `Jmap_core.Request` | 161 + | Emails | `Jmap.Email` | `Jmap_mail.Email` | 162 + | Mailboxes | `Jmap.Mailbox` | `Jmap_mail.Mailbox` | 163 + | Client | `Jmap.Client` | `Jmap_client` | 164 + 165 + ## Need Help? 166 + 167 + - See `jmap/lib/jmap.mli` for the complete unified API documentation 168 + - Check `jmap/test/test_unified_api.ml` for working examples 169 + - Refer to `jmap/test/test_fastmail.ml` for real-world usage
+11
stack/jmap/dune-project
··· 40 40 (jmap-mail (= :version)))) 41 41 42 42 (package 43 + (name jmap) 44 + (synopsis "Unified JMAP library combining core, mail, and client") 45 + (description "Ergonomic, unified interface to the complete JMAP library (RFC 8620, RFC 8621). This is the recommended entry point for most users.") 46 + (depends 47 + (ocaml (>= 4.14)) 48 + (dune (>= 3.0)) 49 + (jmap-core (= :version)) 50 + (jmap-mail (= :version)) 51 + (jmap-client (= :version)))) 52 + 53 + (package 43 54 (name jmap-test) 44 55 (synopsis "Test suite for JMAP libraries") 45 56 (allow_empty)
+8 -8
stack/jmap/jmap-client/jmap_client.ml
··· 5 5 get_request : timeout:Requests.Timeout.t -> string -> Requests.Response.t; 6 6 post_request : timeout:Requests.Timeout.t -> headers:Requests.Headers.t -> body:Requests.Body.t -> string -> Requests.Response.t; 7 7 conn : Jmap_connection.t; 8 - session : Jmap_core.Jmap_session.t option ref; 8 + session : Jmap_core.Session.t option ref; 9 9 } 10 10 11 11 let create ~sw ~env ~conn ~session_url () = ··· 46 46 Buffer.contents buf 47 47 in 48 48 49 - let session = Jmap_core.Jmap_session.Parser.of_string body_str in 49 + let session = Jmap_core.Session.Parser.of_string body_str in 50 50 t.session := Some session; 51 51 session 52 52 ··· 57 57 58 58 let call t req = 59 59 let session = get_session t in 60 - let api_url = Jmap_core.Jmap_session.api_url session in 60 + let api_url = Jmap_core.Session.api_url session in 61 61 let config = Jmap_connection.config t.conn in 62 62 let timeout = Requests.Timeout.create ~total:(Jmap_connection.timeout config) () in 63 63 64 64 (* Convert request to JSON *) 65 - let req_json = Jmap_core.Jmap_request.to_json req in 65 + let req_json = Jmap_core.Request.to_json req in 66 66 67 67 (* Set up headers *) 68 68 let headers = Requests.Headers.(empty ··· 86 86 (Requests.Response.status_code response)) 87 87 ); 88 88 89 - Jmap_core.Jmap_response.Parser.of_string body_str 89 + Jmap_core.Response.Parser.of_string body_str 90 90 91 91 let upload t ~account_id ~content_type:ct data = 92 92 let session = get_session t in 93 - let upload_url = Jmap_core.Jmap_session.upload_url session in 93 + let upload_url = Jmap_core.Session.upload_url session in 94 94 let config = Jmap_connection.config t.conn in 95 95 let timeout = Requests.Timeout.create ~total:(Jmap_connection.timeout config) () in 96 96 ··· 115 115 in 116 116 117 117 let json = Ezjsonm.value_from_string body_str in 118 - Jmap_core.Jmap_binary.Upload.of_json json 118 + Jmap_core.Binary.Upload.of_json json 119 119 120 120 let download t ~account_id ~blob_id ~name = 121 121 let session = get_session t in 122 - let download_url = Jmap_core.Jmap_session.download_url session in 122 + let download_url = Jmap_core.Session.download_url session in 123 123 let config = Jmap_connection.config t.conn in 124 124 let timeout = Requests.Timeout.create ~total:(Jmap_connection.timeout config) () in 125 125
+4 -4
stack/jmap/jmap-client/jmap_client.mli
··· 18 18 t 19 19 20 20 (** Fetch session from server *) 21 - val fetch_session : t -> Jmap_core.Jmap_session.t 21 + val fetch_session : t -> Jmap_core.Session.t 22 22 23 23 (** Get cached session or fetch if needed *) 24 - val get_session : t -> Jmap_core.Jmap_session.t 24 + val get_session : t -> Jmap_core.Session.t 25 25 26 26 (** Make a JMAP API call *) 27 - val call : t -> Jmap_core.Jmap_request.t -> Jmap_core.Jmap_response.t 27 + val call : t -> Jmap_core.Request.t -> Jmap_core.Response.t 28 28 29 29 (** Upload a blob *) 30 30 val upload : ··· 32 32 account_id:string -> 33 33 content_type:string -> 34 34 string -> 35 - Jmap_core.Jmap_binary.Upload.t 35 + Jmap_core.Binary.Upload.t 36 36 37 37 (** Download a blob *) 38 38 val download :
+1 -1
stack/jmap/jmap-core/dune
··· 1 1 (library 2 2 (name jmap_core) 3 3 (public_name jmap-core) 4 - (libraries ezjsonm jsonm) 4 + (libraries ezjsonm jsonm unix) 5 5 (modules 6 6 jmap_core 7 7 jmap_error
+14 -15
stack/jmap/jmap-core/jmap_core.ml
··· 1 1 (** JMAP Core Protocol Library *) 2 2 3 - (** Re-export all submodules *) 4 - module Jmap_error = Jmap_error 5 - module Jmap_id = Jmap_id 6 - module Jmap_primitives = Jmap_primitives 7 - module Jmap_capability = Jmap_capability 8 - module Jmap_filter = Jmap_filter 9 - module Jmap_comparator = Jmap_comparator 10 - module Jmap_standard_methods = Jmap_standard_methods 11 - module Jmap_invocation = Jmap_invocation 12 - module Jmap_request = Jmap_request 13 - module Jmap_response = Jmap_response 14 - module Jmap_session = Jmap_session 15 - module Jmap_push = Jmap_push 16 - module Jmap_binary = Jmap_binary 17 - module Jmap_parser = Jmap_parser 3 + module Error = Jmap_error 4 + module Id = Jmap_id 5 + module Primitives = Jmap_primitives 6 + module Capability = Jmap_capability 7 + module Filter = Jmap_filter 8 + module Comparator = Jmap_comparator 9 + module Standard_methods = Jmap_standard_methods 10 + module Invocation = Jmap_invocation 11 + module Request = Jmap_request 12 + module Response = Jmap_response 13 + module Session = Jmap_session 14 + module Push = Jmap_push 15 + module Binary = Jmap_binary 16 + module Parser = Jmap_parser
+14 -15
stack/jmap/jmap-core/jmap_core.mli
··· 1 1 (** JMAP Core Protocol Library *) 2 2 3 - (** Re-export all submodules *) 4 - module Jmap_error = Jmap_error 5 - module Jmap_id = Jmap_id 6 - module Jmap_primitives = Jmap_primitives 7 - module Jmap_capability = Jmap_capability 8 - module Jmap_filter = Jmap_filter 9 - module Jmap_comparator = Jmap_comparator 10 - module Jmap_standard_methods = Jmap_standard_methods 11 - module Jmap_invocation = Jmap_invocation 12 - module Jmap_request = Jmap_request 13 - module Jmap_response = Jmap_response 14 - module Jmap_session = Jmap_session 15 - module Jmap_push = Jmap_push 16 - module Jmap_binary = Jmap_binary 17 - module Jmap_parser = Jmap_parser 3 + module Error = Jmap_error 4 + module Id = Jmap_id 5 + module Primitives = Jmap_primitives 6 + module Capability = Jmap_capability 7 + module Filter = Jmap_filter 8 + module Comparator = Jmap_comparator 9 + module Standard_methods = Jmap_standard_methods 10 + module Invocation = Jmap_invocation 11 + module Request = Jmap_request 12 + module Response = Jmap_response 13 + module Session = Jmap_session 14 + module Push = Jmap_push 15 + module Binary = Jmap_binary 16 + module Parser = Jmap_parser
+203 -203
stack/jmap/jmap-mail/jmap_email.ml
··· 39 39 } 40 40 *) 41 41 let of_json json = 42 - let open Jmap_core.Jmap_parser.Helpers in 42 + let open Jmap_core.Parser.Helpers in 43 43 let fields = expect_object json in 44 44 let name = get_string_opt "name" fields in 45 45 let email = get_string "email" fields in ··· 70 70 } 71 71 72 72 let of_json json = 73 - let open Jmap_core.Jmap_parser.Helpers in 73 + let open Jmap_core.Parser.Helpers in 74 74 let fields = expect_object json in 75 75 let name = get_string "name" fields in 76 76 let value = get_string "value" fields in ··· 95 95 module BodyPart = struct 96 96 type t = { 97 97 part_id : string option; (** Part ID for referencing this part *) 98 - blob_id : Jmap_core.Jmap_id.t option; (** Blob ID for fetching raw content *) 99 - size : Jmap_core.Jmap_primitives.UnsignedInt.t; (** Size in octets *) 98 + blob_id : Jmap_core.Id.t option; (** Blob ID for fetching raw content *) 99 + size : Jmap_core.Primitives.UnsignedInt.t; (** Size in octets *) 100 100 headers : EmailHeader.t list; (** All header fields *) 101 101 name : string option; (** Name from Content-Disposition or Content-Type *) 102 102 type_ : string; (** Content-Type value (e.g., "text/plain") *) ··· 132 132 } 133 133 *) 134 134 let rec of_json json = 135 - let open Jmap_core.Jmap_parser.Helpers in 135 + let open Jmap_core.Parser.Helpers in 136 136 let fields = expect_object json in 137 137 let part_id = get_string_opt "partId" fields in 138 138 let blob_id = match find_field "blobId" fields with 139 - | Some (`String s) -> Some (Jmap_core.Jmap_id.of_string s) 139 + | Some (`String s) -> Some (Jmap_core.Id.of_string s) 140 140 | Some `Null | None -> None 141 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "blobId must be a string") 141 + | Some _ -> raise (Jmap_core.Error.Parse_error "blobId must be a string") 142 142 in 143 143 let size = match find_field "size" fields with 144 - | Some s -> Jmap_core.Jmap_primitives.UnsignedInt.of_json s 145 - | None -> Jmap_core.Jmap_primitives.UnsignedInt.of_int 0 144 + | Some s -> Jmap_core.Primitives.UnsignedInt.of_json s 145 + | None -> Jmap_core.Primitives.UnsignedInt.of_int 0 146 146 in 147 147 let headers = match find_field "headers" fields with 148 148 | Some (`A items) -> List.map EmailHeader.of_json items 149 149 | Some `Null | None -> [] 150 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "headers must be an array") 150 + | Some _ -> raise (Jmap_core.Error.Parse_error "headers must be an array") 151 151 in 152 152 let name = get_string_opt "name" fields in 153 153 let type_ = get_string "type" fields in ··· 157 157 let language = match find_field "language" fields with 158 158 | Some (`A items) -> Some (List.map expect_string items) 159 159 | Some `Null | None -> None 160 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "language must be an array") 160 + | Some _ -> raise (Jmap_core.Error.Parse_error "language must be an array") 161 161 in 162 162 let location = get_string_opt "location" fields in 163 163 let sub_parts = match find_field "subParts" fields with 164 164 | Some (`A items) -> Some (List.map of_json items) 165 165 | Some `Null | None -> None 166 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "subParts must be an array") 166 + | Some _ -> raise (Jmap_core.Error.Parse_error "subParts must be an array") 167 167 in 168 168 { part_id; blob_id; size; headers; name; type_; charset; 169 169 disposition; cid; language; location; sub_parts } ··· 175 175 | None -> fields 176 176 in 177 177 let fields = match t.blob_id with 178 - | Some id -> ("blobId", Jmap_core.Jmap_id.to_json id) :: fields 178 + | Some id -> ("blobId", Jmap_core.Id.to_json id) :: fields 179 179 | None -> fields 180 180 in 181 - let fields = ("size", Jmap_core.Jmap_primitives.UnsignedInt.to_json t.size) :: fields in 181 + let fields = ("size", Jmap_core.Primitives.UnsignedInt.to_json t.size) :: fields in 182 182 let fields = if t.headers <> [] then 183 183 ("headers", `A (List.map EmailHeader.to_json t.headers)) :: fields 184 184 else ··· 254 254 } 255 255 *) 256 256 let of_json json = 257 - let open Jmap_core.Jmap_parser.Helpers in 257 + let open Jmap_core.Parser.Helpers in 258 258 let fields = expect_object json in 259 259 let value = get_string "value" fields in 260 260 let is_encoding_problem = get_bool_opt "isEncodingProblem" fields false in ··· 281 281 (** Email object type (RFC 8621 Section 4.1) *) 282 282 type t = { 283 283 (* Metadata properties *) 284 - id : Jmap_core.Jmap_id.t; (** Immutable server-assigned id *) 285 - blob_id : Jmap_core.Jmap_id.t; (** Blob ID for downloading raw message *) 286 - thread_id : Jmap_core.Jmap_id.t; (** Thread ID this email belongs to *) 287 - mailbox_ids : (Jmap_core.Jmap_id.t * bool) list; (** Map of mailbox IDs to true *) 284 + id : Jmap_core.Id.t; (** Immutable server-assigned id *) 285 + blob_id : Jmap_core.Id.t; (** Blob ID for downloading raw message *) 286 + thread_id : Jmap_core.Id.t; (** Thread ID this email belongs to *) 287 + mailbox_ids : (Jmap_core.Id.t * bool) list; (** Map of mailbox IDs to true *) 288 288 keywords : (string * bool) list; (** Map of keywords to true (e.g., "$seen") *) 289 - size : Jmap_core.Jmap_primitives.UnsignedInt.t; (** Size in octets *) 290 - received_at : Jmap_core.Jmap_primitives.UTCDate.t; (** Date message was received *) 289 + size : Jmap_core.Primitives.UnsignedInt.t; (** Size in octets *) 290 + received_at : Jmap_core.Primitives.UTCDate.t; (** Date message was received *) 291 291 292 292 (* Header properties - commonly used headers *) 293 293 message_id : string list option; (** Message-ID header field values *) ··· 300 300 bcc : EmailAddress.t list option; (** Bcc header *) 301 301 reply_to : EmailAddress.t list option; (** Reply-To header *) 302 302 subject : string option; (** Subject header *) 303 - sent_at : Jmap_core.Jmap_primitives.Date.t option; (** Date header *) 303 + sent_at : Jmap_core.Primitives.Date.t option; (** Date header *) 304 304 305 305 (* Body properties *) 306 306 body_structure : BodyPart.t option; (** Full MIME structure *) ··· 365 365 } 366 366 *) 367 367 let of_json json = 368 - let open Jmap_core.Jmap_parser.Helpers in 368 + let open Jmap_core.Parser.Helpers in 369 369 let fields = expect_object json in 370 370 371 371 (* Required fields *) 372 - let id = Jmap_core.Jmap_id.of_json (require_field "id" fields) in 373 - let blob_id = Jmap_core.Jmap_id.of_json (require_field "blobId" fields) in 374 - let thread_id = Jmap_core.Jmap_id.of_json (require_field "threadId" fields) in 372 + let id = Jmap_core.Id.of_json (require_field "id" fields) in 373 + let blob_id = Jmap_core.Id.of_json (require_field "blobId" fields) in 374 + let thread_id = Jmap_core.Id.of_json (require_field "threadId" fields) in 375 375 376 376 (* mailboxIds - map of id -> bool *) 377 377 let mailbox_ids = match require_field "mailboxIds" fields with 378 378 | `O map_fields -> 379 379 List.map (fun (k, v) -> 380 - (Jmap_core.Jmap_id.of_string k, expect_bool v) 380 + (Jmap_core.Id.of_string k, expect_bool v) 381 381 ) map_fields 382 - | _ -> raise (Jmap_core.Jmap_error.Parse_error "mailboxIds must be an object") 382 + | _ -> raise (Jmap_core.Error.Parse_error "mailboxIds must be an object") 383 383 in 384 384 385 385 (* keywords - map of string -> bool *) 386 386 let keywords = match require_field "keywords" fields with 387 387 | `O map_fields -> 388 388 List.map (fun (k, v) -> (k, expect_bool v)) map_fields 389 - | _ -> raise (Jmap_core.Jmap_error.Parse_error "keywords must be an object") 389 + | _ -> raise (Jmap_core.Error.Parse_error "keywords must be an object") 390 390 in 391 391 392 - let size = Jmap_core.Jmap_primitives.UnsignedInt.of_json (require_field "size" fields) in 393 - let received_at = Jmap_core.Jmap_primitives.UTCDate.of_json (require_field "receivedAt" fields) in 392 + let size = Jmap_core.Primitives.UnsignedInt.of_json (require_field "size" fields) in 393 + let received_at = Jmap_core.Primitives.UTCDate.of_json (require_field "receivedAt" fields) in 394 394 395 395 (* Optional header fields *) 396 396 let message_id = match find_field "messageId" fields with 397 397 | Some (`A items) -> Some (List.map expect_string items) 398 398 | Some `Null | None -> None 399 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "messageId must be an array") 399 + | Some _ -> raise (Jmap_core.Error.Parse_error "messageId must be an array") 400 400 in 401 401 let in_reply_to = match find_field "inReplyTo" fields with 402 402 | Some (`A items) -> Some (List.map expect_string items) 403 403 | Some `Null | None -> None 404 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "inReplyTo must be an array") 404 + | Some _ -> raise (Jmap_core.Error.Parse_error "inReplyTo must be an array") 405 405 in 406 406 let references = match find_field "references" fields with 407 407 | Some (`A items) -> Some (List.map expect_string items) 408 408 | Some `Null | None -> None 409 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "references must be an array") 409 + | Some _ -> raise (Jmap_core.Error.Parse_error "references must be an array") 410 410 in 411 411 let sender = match find_field "sender" fields with 412 412 | Some (`A items) -> Some (List.map EmailAddress.of_json items) 413 413 | Some `Null | None -> None 414 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "sender must be an array") 414 + | Some _ -> raise (Jmap_core.Error.Parse_error "sender must be an array") 415 415 in 416 416 let from = match find_field "from" fields with 417 417 | Some (`A items) -> Some (List.map EmailAddress.of_json items) 418 418 | Some `Null | None -> None 419 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "from must be an array") 419 + | Some _ -> raise (Jmap_core.Error.Parse_error "from must be an array") 420 420 in 421 421 let to_ = match find_field "to" fields with 422 422 | Some (`A items) -> Some (List.map EmailAddress.of_json items) 423 423 | Some `Null | None -> None 424 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "to must be an array") 424 + | Some _ -> raise (Jmap_core.Error.Parse_error "to must be an array") 425 425 in 426 426 let cc = match find_field "cc" fields with 427 427 | Some (`A items) -> Some (List.map EmailAddress.of_json items) 428 428 | Some `Null | None -> None 429 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "cc must be an array") 429 + | Some _ -> raise (Jmap_core.Error.Parse_error "cc must be an array") 430 430 in 431 431 let bcc = match find_field "bcc" fields with 432 432 | Some (`A items) -> Some (List.map EmailAddress.of_json items) 433 433 | Some `Null | None -> None 434 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "bcc must be an array") 434 + | Some _ -> raise (Jmap_core.Error.Parse_error "bcc must be an array") 435 435 in 436 436 let reply_to = match find_field "replyTo" fields with 437 437 | Some (`A items) -> Some (List.map EmailAddress.of_json items) 438 438 | Some `Null | None -> None 439 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "replyTo must be an array") 439 + | Some _ -> raise (Jmap_core.Error.Parse_error "replyTo must be an array") 440 440 in 441 441 let subject = get_string_opt "subject" fields in 442 442 let sent_at = match find_field "sentAt" fields with 443 - | Some (`String s) -> Some (Jmap_core.Jmap_primitives.Date.of_string s) 443 + | Some (`String s) -> Some (Jmap_core.Primitives.Date.of_string s) 444 444 | Some `Null | None -> None 445 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "sentAt must be a string") 445 + | Some _ -> raise (Jmap_core.Error.Parse_error "sentAt must be a string") 446 446 in 447 447 448 448 (* Body properties *) 449 449 let body_structure = match find_field "bodyStructure" fields with 450 450 | Some ((`O _) as json) -> Some (BodyPart.of_json json) 451 451 | Some `Null | None -> None 452 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "bodyStructure must be an object") 452 + | Some _ -> raise (Jmap_core.Error.Parse_error "bodyStructure must be an object") 453 453 in 454 454 455 455 (* bodyValues - map of partId -> BodyValue *) ··· 457 457 | Some (`O map_fields) -> 458 458 Some (List.map (fun (k, v) -> (k, BodyValue.of_json v)) map_fields) 459 459 | Some `Null | None -> None 460 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "bodyValues must be an object") 460 + | Some _ -> raise (Jmap_core.Error.Parse_error "bodyValues must be an object") 461 461 in 462 462 463 463 let text_body = match find_field "textBody" fields with 464 464 | Some (`A items) -> Some (List.map BodyPart.of_json items) 465 465 | Some `Null | None -> None 466 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "textBody must be an array") 466 + | Some _ -> raise (Jmap_core.Error.Parse_error "textBody must be an array") 467 467 in 468 468 let html_body = match find_field "htmlBody" fields with 469 469 | Some (`A items) -> Some (List.map BodyPart.of_json items) 470 470 | Some `Null | None -> None 471 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "htmlBody must be an array") 471 + | Some _ -> raise (Jmap_core.Error.Parse_error "htmlBody must be an array") 472 472 in 473 473 let attachments = match find_field "attachments" fields with 474 474 | Some (`A items) -> Some (List.map BodyPart.of_json items) 475 475 | Some `Null | None -> None 476 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "attachments must be an array") 476 + | Some _ -> raise (Jmap_core.Error.Parse_error "attachments must be an array") 477 477 in 478 478 479 479 let has_attachment = get_bool_opt "hasAttachment" fields false in ··· 486 486 487 487 let to_json t = 488 488 let fields = [ 489 - ("id", Jmap_core.Jmap_id.to_json t.id); 490 - ("blobId", Jmap_core.Jmap_id.to_json t.blob_id); 491 - ("threadId", Jmap_core.Jmap_id.to_json t.thread_id); 489 + ("id", Jmap_core.Id.to_json t.id); 490 + ("blobId", Jmap_core.Id.to_json t.blob_id); 491 + ("threadId", Jmap_core.Id.to_json t.thread_id); 492 492 ("mailboxIds", `O (List.map (fun (id, b) -> 493 - (Jmap_core.Jmap_id.to_string id, `Bool b)) t.mailbox_ids)); 493 + (Jmap_core.Id.to_string id, `Bool b)) t.mailbox_ids)); 494 494 ("keywords", `O (List.map (fun (k, b) -> (k, `Bool b)) t.keywords)); 495 - ("size", Jmap_core.Jmap_primitives.UnsignedInt.to_json t.size); 496 - ("receivedAt", Jmap_core.Jmap_primitives.UTCDate.to_json t.received_at); 495 + ("size", Jmap_core.Primitives.UnsignedInt.to_json t.size); 496 + ("receivedAt", Jmap_core.Primitives.UTCDate.to_json t.received_at); 497 497 ("hasAttachment", `Bool t.has_attachment); 498 498 ("preview", `String t.preview); 499 499 ] in ··· 540 540 | None -> fields 541 541 in 542 542 let fields = match t.sent_at with 543 - | Some d -> ("sentAt", Jmap_core.Jmap_primitives.Date.to_json d) :: fields 543 + | Some d -> ("sentAt", Jmap_core.Primitives.Date.to_json d) :: fields 544 544 | None -> fields 545 545 in 546 546 let fields = match t.body_structure with ··· 569 569 (** Email-specific filter for /query (RFC 8621 Section 4.4) *) 570 570 module Filter = struct 571 571 type t = { 572 - in_mailbox : Jmap_core.Jmap_id.t option; (** Email is in this mailbox *) 573 - in_mailbox_other_than : Jmap_core.Jmap_id.t list option; (** Email is in a mailbox other than these *) 574 - before : Jmap_core.Jmap_primitives.UTCDate.t option; (** receivedAt < this date *) 575 - after : Jmap_core.Jmap_primitives.UTCDate.t option; (** receivedAt >= this date *) 576 - min_size : Jmap_core.Jmap_primitives.UnsignedInt.t option; (** size >= this value *) 577 - max_size : Jmap_core.Jmap_primitives.UnsignedInt.t option; (** size < this value *) 572 + in_mailbox : Jmap_core.Id.t option; (** Email is in this mailbox *) 573 + in_mailbox_other_than : Jmap_core.Id.t list option; (** Email is in a mailbox other than these *) 574 + before : Jmap_core.Primitives.UTCDate.t option; (** receivedAt < this date *) 575 + after : Jmap_core.Primitives.UTCDate.t option; (** receivedAt >= this date *) 576 + min_size : Jmap_core.Primitives.UnsignedInt.t option; (** size >= this value *) 577 + max_size : Jmap_core.Primitives.UnsignedInt.t option; (** size < this value *) 578 578 all_in_thread_have_keyword : string option; (** All emails in thread have this keyword *) 579 579 some_in_thread_have_keyword : string option; (** Some email in thread has this keyword *) 580 580 none_in_thread_have_keyword : string option; (** No email in thread has this keyword *) ··· 592 592 } 593 593 594 594 let of_json json = 595 - let open Jmap_core.Jmap_parser.Helpers in 595 + let open Jmap_core.Parser.Helpers in 596 596 let fields = expect_object json in 597 597 let in_mailbox = match find_field "inMailbox" fields with 598 - | Some (`String s) -> Some (Jmap_core.Jmap_id.of_string s) 598 + | Some (`String s) -> Some (Jmap_core.Id.of_string s) 599 599 | Some `Null | None -> None 600 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "inMailbox must be a string") 600 + | Some _ -> raise (Jmap_core.Error.Parse_error "inMailbox must be a string") 601 601 in 602 602 let in_mailbox_other_than = match find_field "inMailboxOtherThan" fields with 603 - | Some (`A items) -> Some (List.map (fun s -> Jmap_core.Jmap_id.of_json s) items) 603 + | Some (`A items) -> Some (List.map (fun s -> Jmap_core.Id.of_json s) items) 604 604 | Some `Null | None -> None 605 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "inMailboxOtherThan must be an array") 605 + | Some _ -> raise (Jmap_core.Error.Parse_error "inMailboxOtherThan must be an array") 606 606 in 607 607 let before = match find_field "before" fields with 608 - | Some (`String s) -> Some (Jmap_core.Jmap_primitives.UTCDate.of_string s) 608 + | Some (`String s) -> Some (Jmap_core.Primitives.UTCDate.of_string s) 609 609 | Some `Null | None -> None 610 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "before must be a string") 610 + | Some _ -> raise (Jmap_core.Error.Parse_error "before must be a string") 611 611 in 612 612 let after = match find_field "after" fields with 613 - | Some (`String s) -> Some (Jmap_core.Jmap_primitives.UTCDate.of_string s) 613 + | Some (`String s) -> Some (Jmap_core.Primitives.UTCDate.of_string s) 614 614 | Some `Null | None -> None 615 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "after must be a string") 615 + | Some _ -> raise (Jmap_core.Error.Parse_error "after must be a string") 616 616 in 617 617 let min_size = match find_field "minSize" fields with 618 - | Some s -> Some (Jmap_core.Jmap_primitives.UnsignedInt.of_json s) 618 + | Some s -> Some (Jmap_core.Primitives.UnsignedInt.of_json s) 619 619 | None -> None 620 620 in 621 621 let max_size = match find_field "maxSize" fields with 622 - | Some s -> Some (Jmap_core.Jmap_primitives.UnsignedInt.of_json s) 622 + | Some s -> Some (Jmap_core.Primitives.UnsignedInt.of_json s) 623 623 | None -> None 624 624 in 625 625 let all_in_thread_have_keyword = get_string_opt "allInThreadHaveKeyword" fields in ··· 630 630 let has_attachment = match find_field "hasAttachment" fields with 631 631 | Some (`Bool b) -> Some b 632 632 | Some `Null | None -> None 633 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "hasAttachment must be a boolean") 633 + | Some _ -> raise (Jmap_core.Error.Parse_error "hasAttachment must be a boolean") 634 634 in 635 635 let text = get_string_opt "text" fields in 636 636 let from = get_string_opt "from" fields in ··· 648 648 (name, value) 649 649 ) items) 650 650 | Some `Null | None -> None 651 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "header must be an array") 651 + | Some _ -> raise (Jmap_core.Error.Parse_error "header must be an array") 652 652 in 653 653 { in_mailbox; in_mailbox_other_than; before; after; min_size; max_size; 654 654 all_in_thread_have_keyword; some_in_thread_have_keyword; ··· 691 691 let to_json t = 692 692 let fields = [] in 693 693 let fields = match t.in_mailbox with 694 - | Some id -> ("inMailbox", Jmap_core.Jmap_id.to_json id) :: fields 694 + | Some id -> ("inMailbox", Jmap_core.Id.to_json id) :: fields 695 695 | None -> fields 696 696 in 697 697 let fields = match t.in_mailbox_other_than with 698 - | Some ids -> ("inMailboxOtherThan", `A (List.map Jmap_core.Jmap_id.to_json ids)) :: fields 698 + | Some ids -> ("inMailboxOtherThan", `A (List.map Jmap_core.Id.to_json ids)) :: fields 699 699 | None -> fields 700 700 in 701 701 let fields = match t.before with 702 - | Some d -> ("before", `String (Jmap_core.Jmap_primitives.UTCDate.to_string d)) :: fields 702 + | Some d -> ("before", `String (Jmap_core.Primitives.UTCDate.to_string d)) :: fields 703 703 | None -> fields 704 704 in 705 705 let fields = match t.after with 706 - | Some d -> ("after", `String (Jmap_core.Jmap_primitives.UTCDate.to_string d)) :: fields 706 + | Some d -> ("after", `String (Jmap_core.Primitives.UTCDate.to_string d)) :: fields 707 707 | None -> fields 708 708 in 709 709 let fields = match t.min_size with 710 - | Some s -> ("minSize", Jmap_core.Jmap_primitives.UnsignedInt.to_json s) :: fields 710 + | Some s -> ("minSize", Jmap_core.Primitives.UnsignedInt.to_json s) :: fields 711 711 | None -> fields 712 712 in 713 713 let fields = match t.max_size with 714 - | Some s -> ("maxSize", Jmap_core.Jmap_primitives.UnsignedInt.to_json s) :: fields 714 + | Some s -> ("maxSize", Jmap_core.Primitives.UnsignedInt.to_json s) :: fields 715 715 | None -> fields 716 716 in 717 717 let fields = match t.all_in_thread_have_keyword with ··· 780 780 (** Standard /get method (RFC 8621 Section 4.2) *) 781 781 module Get = struct 782 782 type request = { 783 - account_id : Jmap_core.Jmap_id.t; 784 - ids : Jmap_core.Jmap_id.t list option; 783 + account_id : Jmap_core.Id.t; 784 + ids : Jmap_core.Id.t list option; 785 785 properties : string list option; 786 786 (* Email-specific get arguments *) 787 787 body_properties : string list option; (** Properties to fetch for bodyStructure parts *) 788 788 fetch_text_body_values : bool option; (** Fetch bodyValues for textBody parts *) 789 789 fetch_html_body_values : bool option; (** Fetch bodyValues for htmlBody parts *) 790 790 fetch_all_body_values : bool option; (** Fetch bodyValues for all parts *) 791 - max_body_value_bytes : Jmap_core.Jmap_primitives.UnsignedInt.t option; (** Truncate large body values *) 791 + max_body_value_bytes : Jmap_core.Primitives.UnsignedInt.t option; (** Truncate large body values *) 792 792 } 793 793 794 - type response = t Jmap_core.Jmap_standard_methods.Get.response 794 + type response = t Jmap_core.Standard_methods.Get.response 795 795 796 796 (* Accessors for request *) 797 797 let account_id req = req.account_id ··· 816 816 - test/data/mail/email_get_full_request.json 817 817 *) 818 818 let request_of_json json = 819 - let open Jmap_core.Jmap_parser.Helpers in 819 + let open Jmap_core.Parser.Helpers in 820 820 let fields = expect_object json in 821 - let account_id = Jmap_core.Jmap_id.of_json (require_field "accountId" fields) in 821 + let account_id = Jmap_core.Id.of_json (require_field "accountId" fields) in 822 822 let ids = match find_field "ids" fields with 823 - | Some (`A items) -> Some (List.map Jmap_core.Jmap_id.of_json items) 823 + | Some (`A items) -> Some (List.map Jmap_core.Id.of_json items) 824 824 | Some `Null | None -> None 825 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "ids must be an array") 825 + | Some _ -> raise (Jmap_core.Error.Parse_error "ids must be an array") 826 826 in 827 827 let properties = match find_field "properties" fields with 828 828 | Some (`A items) -> Some (List.map expect_string items) 829 829 | Some `Null | None -> None 830 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "properties must be an array") 830 + | Some _ -> raise (Jmap_core.Error.Parse_error "properties must be an array") 831 831 in 832 832 let body_properties = match find_field "bodyProperties" fields with 833 833 | Some (`A items) -> Some (List.map expect_string items) 834 834 | Some `Null | None -> None 835 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "bodyProperties must be an array") 835 + | Some _ -> raise (Jmap_core.Error.Parse_error "bodyProperties must be an array") 836 836 in 837 837 let fetch_text_body_values = match find_field "fetchTextBodyValues" fields with 838 838 | Some (`Bool b) -> Some b 839 839 | Some `Null | None -> None 840 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "fetchTextBodyValues must be a boolean") 840 + | Some _ -> raise (Jmap_core.Error.Parse_error "fetchTextBodyValues must be a boolean") 841 841 in 842 842 let fetch_html_body_values = match find_field "fetchHTMLBodyValues" fields with 843 843 | Some (`Bool b) -> Some b 844 844 | Some `Null | None -> None 845 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "fetchHTMLBodyValues must be a boolean") 845 + | Some _ -> raise (Jmap_core.Error.Parse_error "fetchHTMLBodyValues must be a boolean") 846 846 in 847 847 let fetch_all_body_values = match find_field "fetchAllBodyValues" fields with 848 848 | Some (`Bool b) -> Some b 849 849 | Some `Null | None -> None 850 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "fetchAllBodyValues must be a boolean") 850 + | Some _ -> raise (Jmap_core.Error.Parse_error "fetchAllBodyValues must be a boolean") 851 851 in 852 852 let max_body_value_bytes = match find_field "maxBodyValueBytes" fields with 853 - | Some v -> Some (Jmap_core.Jmap_primitives.UnsignedInt.of_json v) 853 + | Some v -> Some (Jmap_core.Primitives.UnsignedInt.of_json v) 854 854 | None -> None 855 855 in 856 856 { account_id; ids; properties; body_properties; fetch_text_body_values; ··· 862 862 - test/data/mail/email_get_full_response.json 863 863 *) 864 864 let response_of_json json = 865 - Jmap_core.Jmap_standard_methods.Get.response_of_json of_json json 865 + Jmap_core.Standard_methods.Get.response_of_json of_json json 866 866 867 867 (** Convert get request to JSON *) 868 868 let request_to_json req = 869 869 let fields = [ 870 - ("accountId", Jmap_core.Jmap_id.to_json req.account_id); 870 + ("accountId", Jmap_core.Id.to_json req.account_id); 871 871 ] in 872 872 let fields = match req.ids with 873 - | Some ids -> ("ids", `A (List.map Jmap_core.Jmap_id.to_json ids)) :: fields 873 + | Some ids -> ("ids", `A (List.map Jmap_core.Id.to_json ids)) :: fields 874 874 | None -> fields 875 875 in 876 876 let fields = match req.properties with ··· 894 894 | None -> fields 895 895 in 896 896 let fields = match req.max_body_value_bytes with 897 - | Some mbvb -> ("maxBodyValueBytes", Jmap_core.Jmap_primitives.UnsignedInt.to_json mbvb) :: fields 897 + | Some mbvb -> ("maxBodyValueBytes", Jmap_core.Primitives.UnsignedInt.to_json mbvb) :: fields 898 898 | None -> fields 899 899 in 900 900 `O fields ··· 902 902 903 903 (** Standard /changes method (RFC 8621 Section 4.3) *) 904 904 module Changes = struct 905 - type request = Jmap_core.Jmap_standard_methods.Changes.request 906 - type response = Jmap_core.Jmap_standard_methods.Changes.response 905 + type request = Jmap_core.Standard_methods.Changes.request 906 + type response = Jmap_core.Standard_methods.Changes.response 907 907 908 908 let request_of_json json = 909 - Jmap_core.Jmap_standard_methods.Changes.request_of_json json 909 + Jmap_core.Standard_methods.Changes.request_of_json json 910 910 911 911 let response_of_json json = 912 - Jmap_core.Jmap_standard_methods.Changes.response_of_json json 912 + Jmap_core.Standard_methods.Changes.response_of_json json 913 913 end 914 914 915 915 (** Standard /query method (RFC 8621 Section 4.4) *) 916 916 module Query = struct 917 917 type request = { 918 - account_id : Jmap_core.Jmap_id.t; 919 - filter : Filter.t Jmap_core.Jmap_filter.t option; 920 - sort : Jmap_core.Jmap_comparator.t list option; 921 - position : Jmap_core.Jmap_primitives.Int53.t option; 922 - anchor : Jmap_core.Jmap_id.t option; 923 - anchor_offset : Jmap_core.Jmap_primitives.Int53.t option; 924 - limit : Jmap_core.Jmap_primitives.UnsignedInt.t option; 918 + account_id : Jmap_core.Id.t; 919 + filter : Filter.t Jmap_core.Filter.t option; 920 + sort : Jmap_core.Comparator.t list option; 921 + position : Jmap_core.Primitives.Int53.t option; 922 + anchor : Jmap_core.Id.t option; 923 + anchor_offset : Jmap_core.Primitives.Int53.t option; 924 + limit : Jmap_core.Primitives.UnsignedInt.t option; 925 925 calculate_total : bool option; 926 926 (* Email-specific query arguments *) 927 927 collapse_threads : bool option; (** Return only one email per thread *) 928 928 } 929 929 930 - type response = Jmap_core.Jmap_standard_methods.Query.response 930 + type response = Jmap_core.Standard_methods.Query.response 931 931 932 932 (* Accessors for request *) 933 933 let account_id req = req.account_id ··· 949 949 (** Parse query request from JSON. 950 950 Test files: test/data/mail/email_query_request.json *) 951 951 let request_of_json json = 952 - let open Jmap_core.Jmap_parser.Helpers in 952 + let open Jmap_core.Parser.Helpers in 953 953 let fields = expect_object json in 954 - let account_id = Jmap_core.Jmap_id.of_json (require_field "accountId" fields) in 954 + let account_id = Jmap_core.Id.of_json (require_field "accountId" fields) in 955 955 let filter = match find_field "filter" fields with 956 - | Some v -> Some (Jmap_core.Jmap_filter.of_json Filter.of_json v) 956 + | Some v -> Some (Jmap_core.Filter.of_json Filter.of_json v) 957 957 | None -> None 958 958 in 959 959 let sort = match find_field "sort" fields with 960 - | Some (`A items) -> Some (List.map Jmap_core.Jmap_comparator.of_json items) 960 + | Some (`A items) -> Some (List.map Jmap_core.Comparator.of_json items) 961 961 | Some `Null | None -> None 962 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "sort must be an array") 962 + | Some _ -> raise (Jmap_core.Error.Parse_error "sort must be an array") 963 963 in 964 964 let position = match find_field "position" fields with 965 - | Some v -> Some (Jmap_core.Jmap_primitives.Int53.of_json v) 965 + | Some v -> Some (Jmap_core.Primitives.Int53.of_json v) 966 966 | None -> None 967 967 in 968 968 let anchor = match find_field "anchor" fields with 969 - | Some (`String s) -> Some (Jmap_core.Jmap_id.of_string s) 969 + | Some (`String s) -> Some (Jmap_core.Id.of_string s) 970 970 | Some `Null | None -> None 971 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "anchor must be a string") 971 + | Some _ -> raise (Jmap_core.Error.Parse_error "anchor must be a string") 972 972 in 973 973 let anchor_offset = match find_field "anchorOffset" fields with 974 - | Some v -> Some (Jmap_core.Jmap_primitives.Int53.of_json v) 974 + | Some v -> Some (Jmap_core.Primitives.Int53.of_json v) 975 975 | None -> None 976 976 in 977 977 let limit = match find_field "limit" fields with 978 - | Some v -> Some (Jmap_core.Jmap_primitives.UnsignedInt.of_json v) 978 + | Some v -> Some (Jmap_core.Primitives.UnsignedInt.of_json v) 979 979 | None -> None 980 980 in 981 981 let calculate_total = match find_field "calculateTotal" fields with 982 982 | Some (`Bool b) -> Some b 983 983 | Some `Null | None -> None 984 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "calculateTotal must be a boolean") 984 + | Some _ -> raise (Jmap_core.Error.Parse_error "calculateTotal must be a boolean") 985 985 in 986 986 let collapse_threads = match find_field "collapseThreads" fields with 987 987 | Some (`Bool b) -> Some b 988 988 | Some `Null | None -> None 989 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "collapseThreads must be a boolean") 989 + | Some _ -> raise (Jmap_core.Error.Parse_error "collapseThreads must be a boolean") 990 990 in 991 991 { account_id; filter; sort; position; anchor; anchor_offset; 992 992 limit; calculate_total; collapse_threads } ··· 994 994 (** Parse query response from JSON. 995 995 Test files: test/data/mail/email_query_response.json *) 996 996 let response_of_json json = 997 - Jmap_core.Jmap_standard_methods.Query.response_of_json json 997 + Jmap_core.Standard_methods.Query.response_of_json json 998 998 999 999 (** Convert query request to JSON *) 1000 1000 let request_to_json req = 1001 1001 let fields = [ 1002 - ("accountId", Jmap_core.Jmap_id.to_json req.account_id); 1002 + ("accountId", Jmap_core.Id.to_json req.account_id); 1003 1003 ] in 1004 1004 let fields = match req.filter with 1005 - | Some f -> ("filter", Jmap_core.Jmap_filter.to_json Filter.to_json f) :: fields 1005 + | Some f -> ("filter", Jmap_core.Filter.to_json Filter.to_json f) :: fields 1006 1006 | None -> fields 1007 1007 in 1008 1008 let fields = match req.sort with 1009 - | Some s -> ("sort", `A (List.map Jmap_core.Jmap_comparator.to_json s)) :: fields 1009 + | Some s -> ("sort", `A (List.map Jmap_core.Comparator.to_json s)) :: fields 1010 1010 | None -> fields 1011 1011 in 1012 1012 let fields = match req.position with 1013 - | Some p -> ("position", Jmap_core.Jmap_primitives.Int53.to_json p) :: fields 1013 + | Some p -> ("position", Jmap_core.Primitives.Int53.to_json p) :: fields 1014 1014 | None -> fields 1015 1015 in 1016 1016 let fields = match req.anchor with 1017 - | Some a -> ("anchor", Jmap_core.Jmap_id.to_json a) :: fields 1017 + | Some a -> ("anchor", Jmap_core.Id.to_json a) :: fields 1018 1018 | None -> fields 1019 1019 in 1020 1020 let fields = match req.anchor_offset with 1021 - | Some ao -> ("anchorOffset", Jmap_core.Jmap_primitives.Int53.to_json ao) :: fields 1021 + | Some ao -> ("anchorOffset", Jmap_core.Primitives.Int53.to_json ao) :: fields 1022 1022 | None -> fields 1023 1023 in 1024 1024 let fields = match req.limit with 1025 - | Some l -> ("limit", Jmap_core.Jmap_primitives.UnsignedInt.to_json l) :: fields 1025 + | Some l -> ("limit", Jmap_core.Primitives.UnsignedInt.to_json l) :: fields 1026 1026 | None -> fields 1027 1027 in 1028 1028 let fields = match req.calculate_total with ··· 1039 1039 (** Standard /queryChanges method (RFC 8621 Section 4.5) *) 1040 1040 module QueryChanges = struct 1041 1041 type request = { 1042 - account_id : Jmap_core.Jmap_id.t; 1043 - filter : Filter.t Jmap_core.Jmap_filter.t option; 1044 - sort : Jmap_core.Jmap_comparator.t list option; 1042 + account_id : Jmap_core.Id.t; 1043 + filter : Filter.t Jmap_core.Filter.t option; 1044 + sort : Jmap_core.Comparator.t list option; 1045 1045 since_query_state : string; 1046 - max_changes : Jmap_core.Jmap_primitives.UnsignedInt.t option; 1047 - up_to_id : Jmap_core.Jmap_id.t option; 1046 + max_changes : Jmap_core.Primitives.UnsignedInt.t option; 1047 + up_to_id : Jmap_core.Id.t option; 1048 1048 calculate_total : bool option; 1049 1049 (* Email-specific *) 1050 1050 collapse_threads : bool option; 1051 1051 } 1052 1052 1053 - type response = Jmap_core.Jmap_standard_methods.QueryChanges.response 1053 + type response = Jmap_core.Standard_methods.QueryChanges.response 1054 1054 1055 1055 (* Accessors for request *) 1056 1056 let account_id req = req.account_id ··· 1069 1069 up_to_id; calculate_total; collapse_threads } 1070 1070 1071 1071 let request_of_json json = 1072 - let open Jmap_core.Jmap_parser.Helpers in 1072 + let open Jmap_core.Parser.Helpers in 1073 1073 let fields = expect_object json in 1074 - let account_id = Jmap_core.Jmap_id.of_json (require_field "accountId" fields) in 1074 + let account_id = Jmap_core.Id.of_json (require_field "accountId" fields) in 1075 1075 let filter = match find_field "filter" fields with 1076 - | Some v -> Some (Jmap_core.Jmap_filter.of_json Filter.of_json v) 1076 + | Some v -> Some (Jmap_core.Filter.of_json Filter.of_json v) 1077 1077 | None -> None 1078 1078 in 1079 1079 let sort = match find_field "sort" fields with 1080 - | Some (`A items) -> Some (List.map Jmap_core.Jmap_comparator.of_json items) 1080 + | Some (`A items) -> Some (List.map Jmap_core.Comparator.of_json items) 1081 1081 | Some `Null | None -> None 1082 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "sort must be an array") 1082 + | Some _ -> raise (Jmap_core.Error.Parse_error "sort must be an array") 1083 1083 in 1084 1084 let since_query_state = get_string "sinceQueryState" fields in 1085 1085 let max_changes = match find_field "maxChanges" fields with 1086 - | Some v -> Some (Jmap_core.Jmap_primitives.UnsignedInt.of_json v) 1086 + | Some v -> Some (Jmap_core.Primitives.UnsignedInt.of_json v) 1087 1087 | None -> None 1088 1088 in 1089 1089 let up_to_id = match find_field "upToId" fields with 1090 - | Some (`String s) -> Some (Jmap_core.Jmap_id.of_string s) 1090 + | Some (`String s) -> Some (Jmap_core.Id.of_string s) 1091 1091 | Some `Null | None -> None 1092 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "upToId must be a string") 1092 + | Some _ -> raise (Jmap_core.Error.Parse_error "upToId must be a string") 1093 1093 in 1094 1094 let calculate_total = match find_field "calculateTotal" fields with 1095 1095 | Some (`Bool b) -> Some b 1096 1096 | Some `Null | None -> None 1097 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "calculateTotal must be a boolean") 1097 + | Some _ -> raise (Jmap_core.Error.Parse_error "calculateTotal must be a boolean") 1098 1098 in 1099 1099 let collapse_threads = match find_field "collapseThreads" fields with 1100 1100 | Some (`Bool b) -> Some b 1101 1101 | Some `Null | None -> None 1102 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "collapseThreads must be a boolean") 1102 + | Some _ -> raise (Jmap_core.Error.Parse_error "collapseThreads must be a boolean") 1103 1103 in 1104 1104 { account_id; filter; sort; since_query_state; max_changes; 1105 1105 up_to_id; calculate_total; collapse_threads } 1106 1106 1107 1107 let response_of_json json = 1108 - Jmap_core.Jmap_standard_methods.QueryChanges.response_of_json json 1108 + Jmap_core.Standard_methods.QueryChanges.response_of_json json 1109 1109 end 1110 1110 1111 1111 (** Standard /set method (RFC 8621 Section 4.6) *) 1112 1112 module Set = struct 1113 - type request = t Jmap_core.Jmap_standard_methods.Set.request 1114 - type response = t Jmap_core.Jmap_standard_methods.Set.response 1113 + type request = t Jmap_core.Standard_methods.Set.request 1114 + type response = t Jmap_core.Standard_methods.Set.response 1115 1115 1116 1116 (** Parse set request from JSON. 1117 1117 Test files: test/data/mail/email_set_request.json *) 1118 1118 let request_of_json json = 1119 - Jmap_core.Jmap_standard_methods.Set.request_of_json of_json json 1119 + Jmap_core.Standard_methods.Set.request_of_json of_json json 1120 1120 1121 1121 (** Parse set response from JSON. 1122 1122 Test files: test/data/mail/email_set_response.json *) 1123 1123 let response_of_json json = 1124 - Jmap_core.Jmap_standard_methods.Set.response_of_json of_json json 1124 + Jmap_core.Standard_methods.Set.response_of_json of_json json 1125 1125 end 1126 1126 1127 1127 (** Standard /copy method (RFC 8621 Section 4.7) *) 1128 1128 module Copy = struct 1129 - type request = t Jmap_core.Jmap_standard_methods.Copy.request 1130 - type response = t Jmap_core.Jmap_standard_methods.Copy.response 1129 + type request = t Jmap_core.Standard_methods.Copy.request 1130 + type response = t Jmap_core.Standard_methods.Copy.response 1131 1131 1132 1132 let request_of_json json = 1133 - Jmap_core.Jmap_standard_methods.Copy.request_of_json of_json json 1133 + Jmap_core.Standard_methods.Copy.request_of_json of_json json 1134 1134 1135 1135 let response_of_json json = 1136 - Jmap_core.Jmap_standard_methods.Copy.response_of_json of_json json 1136 + Jmap_core.Standard_methods.Copy.response_of_json of_json json 1137 1137 end 1138 1138 1139 1139 (** Email/import method (RFC 8621 Section 4.8) *) 1140 1140 module Import = struct 1141 1141 (** Email import request object *) 1142 1142 type import_email = { 1143 - blob_id : Jmap_core.Jmap_id.t; (** Blob ID containing raw RFC 5322 message *) 1144 - mailbox_ids : (Jmap_core.Jmap_id.t * bool) list; (** Mailboxes to add email to *) 1143 + blob_id : Jmap_core.Id.t; (** Blob ID containing raw RFC 5322 message *) 1144 + mailbox_ids : (Jmap_core.Id.t * bool) list; (** Mailboxes to add email to *) 1145 1145 keywords : (string * bool) list; (** Keywords to set *) 1146 - received_at : Jmap_core.Jmap_primitives.UTCDate.t option; (** Override received date *) 1146 + received_at : Jmap_core.Primitives.UTCDate.t option; (** Override received date *) 1147 1147 } 1148 1148 1149 1149 type request = { 1150 - account_id : Jmap_core.Jmap_id.t; 1150 + account_id : Jmap_core.Id.t; 1151 1151 if_in_state : string option; 1152 - emails : (Jmap_core.Jmap_id.t * import_email) list; (** Map of creation id to import object *) 1152 + emails : (Jmap_core.Id.t * import_email) list; (** Map of creation id to import object *) 1153 1153 } 1154 1154 1155 1155 type response = { 1156 - account_id : Jmap_core.Jmap_id.t; 1156 + account_id : Jmap_core.Id.t; 1157 1157 old_state : string option; 1158 1158 new_state : string; 1159 - created : (Jmap_core.Jmap_id.t * t) list option; 1160 - not_created : (Jmap_core.Jmap_id.t * Jmap_core.Jmap_error.set_error_detail) list option; 1159 + created : (Jmap_core.Id.t * t) list option; 1160 + not_created : (Jmap_core.Id.t * Jmap_core.Error.set_error_detail) list option; 1161 1161 } 1162 1162 1163 1163 (* Accessors for import_email *) ··· 1193 1193 (** Parse import request from JSON. 1194 1194 Test files: test/data/mail/email_import_request.json *) 1195 1195 let request_of_json json = 1196 - let open Jmap_core.Jmap_parser.Helpers in 1196 + let open Jmap_core.Parser.Helpers in 1197 1197 let fields = expect_object json in 1198 - let account_id = Jmap_core.Jmap_id.of_json (require_field "accountId" fields) in 1198 + let account_id = Jmap_core.Id.of_json (require_field "accountId" fields) in 1199 1199 let if_in_state = get_string_opt "ifInState" fields in 1200 1200 let emails = match require_field "emails" fields with 1201 1201 | `O pairs -> 1202 1202 List.map (fun (k, v) -> 1203 1203 let ie_fields = expect_object v in 1204 - let blob_id = Jmap_core.Jmap_id.of_json (require_field "blobId" ie_fields) in 1204 + let blob_id = Jmap_core.Id.of_json (require_field "blobId" ie_fields) in 1205 1205 let mailbox_ids = match require_field "mailboxIds" ie_fields with 1206 1206 | `O map_fields -> 1207 1207 List.map (fun (mid, b) -> 1208 - (Jmap_core.Jmap_id.of_string mid, expect_bool b) 1208 + (Jmap_core.Id.of_string mid, expect_bool b) 1209 1209 ) map_fields 1210 - | _ -> raise (Jmap_core.Jmap_error.Parse_error "mailboxIds must be an object") 1210 + | _ -> raise (Jmap_core.Error.Parse_error "mailboxIds must be an object") 1211 1211 in 1212 1212 let keywords = match require_field "keywords" ie_fields with 1213 1213 | `O map_fields -> 1214 1214 List.map (fun (kw, b) -> (kw, expect_bool b)) map_fields 1215 - | _ -> raise (Jmap_core.Jmap_error.Parse_error "keywords must be an object") 1215 + | _ -> raise (Jmap_core.Error.Parse_error "keywords must be an object") 1216 1216 in 1217 1217 let received_at = match find_field "receivedAt" ie_fields with 1218 - | Some (`String s) -> Some (Jmap_core.Jmap_primitives.UTCDate.of_string s) 1218 + | Some (`String s) -> Some (Jmap_core.Primitives.UTCDate.of_string s) 1219 1219 | Some `Null | None -> None 1220 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "receivedAt must be a string") 1220 + | Some _ -> raise (Jmap_core.Error.Parse_error "receivedAt must be a string") 1221 1221 in 1222 1222 let import_email = { blob_id; mailbox_ids; keywords; received_at } in 1223 - (Jmap_core.Jmap_id.of_string k, import_email) 1223 + (Jmap_core.Id.of_string k, import_email) 1224 1224 ) pairs 1225 - | _ -> raise (Jmap_core.Jmap_error.Parse_error "emails must be an object") 1225 + | _ -> raise (Jmap_core.Error.Parse_error "emails must be an object") 1226 1226 in 1227 1227 { account_id; if_in_state; emails } 1228 1228 1229 1229 (** Parse import response from JSON. 1230 1230 Test files: test/data/mail/email_import_response.json *) 1231 1231 let response_of_json json = 1232 - let open Jmap_core.Jmap_parser.Helpers in 1232 + let open Jmap_core.Parser.Helpers in 1233 1233 let fields = expect_object json in 1234 - let account_id = Jmap_core.Jmap_id.of_json (require_field "accountId" fields) in 1234 + let account_id = Jmap_core.Id.of_json (require_field "accountId" fields) in 1235 1235 let old_state = get_string_opt "oldState" fields in 1236 1236 let new_state = get_string "newState" fields in 1237 1237 let created = match find_field "created" fields with 1238 1238 | Some `Null | None -> None 1239 1239 | Some (`O pairs) -> 1240 1240 Some (List.map (fun (k, v) -> 1241 - (Jmap_core.Jmap_id.of_string k, of_json v) 1241 + (Jmap_core.Id.of_string k, of_json v) 1242 1242 ) pairs) 1243 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "created must be an object") 1243 + | Some _ -> raise (Jmap_core.Error.Parse_error "created must be an object") 1244 1244 in 1245 1245 let not_created = match find_field "notCreated" fields with 1246 1246 | Some `Null | None -> None 1247 1247 | Some (`O pairs) -> 1248 1248 Some (List.map (fun (k, v) -> 1249 - (Jmap_core.Jmap_id.of_string k, Jmap_core.Jmap_error.parse_set_error_detail v) 1249 + (Jmap_core.Id.of_string k, Jmap_core.Error.parse_set_error_detail v) 1250 1250 ) pairs) 1251 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "notCreated must be an object") 1251 + | Some _ -> raise (Jmap_core.Error.Parse_error "notCreated must be an object") 1252 1252 in 1253 1253 { account_id; old_state; new_state; created; not_created } 1254 1254 end ··· 1256 1256 (** Email/parse method (RFC 8621 Section 4.9) *) 1257 1257 module Parse = struct 1258 1258 type request = { 1259 - account_id : Jmap_core.Jmap_id.t; 1260 - blob_ids : Jmap_core.Jmap_id.t list; (** Blob IDs to parse *) 1259 + account_id : Jmap_core.Id.t; 1260 + blob_ids : Jmap_core.Id.t list; (** Blob IDs to parse *) 1261 1261 properties : string list option; (** Email properties to return *) 1262 1262 body_properties : string list option; (** BodyPart properties to return *) 1263 1263 fetch_text_body_values : bool option; 1264 1264 fetch_html_body_values : bool option; 1265 1265 fetch_all_body_values : bool option; 1266 - max_body_value_bytes : Jmap_core.Jmap_primitives.UnsignedInt.t option; 1266 + max_body_value_bytes : Jmap_core.Primitives.UnsignedInt.t option; 1267 1267 } 1268 1268 1269 1269 type response = { 1270 - account_id : Jmap_core.Jmap_id.t; 1271 - parsed : (Jmap_core.Jmap_id.t * t) list option; (** Map of blob ID to parsed email *) 1272 - not_parsable : Jmap_core.Jmap_id.t list option; (** Blob IDs that couldn't be parsed *) 1273 - not_found : Jmap_core.Jmap_id.t list option; (** Blob IDs that don't exist *) 1270 + account_id : Jmap_core.Id.t; 1271 + parsed : (Jmap_core.Id.t * t) list option; (** Map of blob ID to parsed email *) 1272 + not_parsable : Jmap_core.Id.t list option; (** Blob IDs that couldn't be parsed *) 1273 + not_found : Jmap_core.Id.t list option; (** Blob IDs that don't exist *) 1274 1274 } 1275 1275 1276 1276 (* Accessors for request *) ··· 1303 1303 (** Parse parse request from JSON. 1304 1304 Test files: test/data/mail/email_parse_request.json *) 1305 1305 let request_of_json json = 1306 - let open Jmap_core.Jmap_parser.Helpers in 1306 + let open Jmap_core.Parser.Helpers in 1307 1307 let fields = expect_object json in 1308 - let account_id = Jmap_core.Jmap_id.of_json (require_field "accountId" fields) in 1308 + let account_id = Jmap_core.Id.of_json (require_field "accountId" fields) in 1309 1309 let blob_ids = match require_field "blobIds" fields with 1310 - | `A items -> List.map Jmap_core.Jmap_id.of_json items 1311 - | _ -> raise (Jmap_core.Jmap_error.Parse_error "blobIds must be an array") 1310 + | `A items -> List.map Jmap_core.Id.of_json items 1311 + | _ -> raise (Jmap_core.Error.Parse_error "blobIds must be an array") 1312 1312 in 1313 1313 let properties = match find_field "properties" fields with 1314 1314 | Some (`A items) -> Some (List.map expect_string items) 1315 1315 | Some `Null | None -> None 1316 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "properties must be an array") 1316 + | Some _ -> raise (Jmap_core.Error.Parse_error "properties must be an array") 1317 1317 in 1318 1318 let body_properties = match find_field "bodyProperties" fields with 1319 1319 | Some (`A items) -> Some (List.map expect_string items) 1320 1320 | Some `Null | None -> None 1321 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "bodyProperties must be an array") 1321 + | Some _ -> raise (Jmap_core.Error.Parse_error "bodyProperties must be an array") 1322 1322 in 1323 1323 let fetch_text_body_values = match find_field "fetchTextBodyValues" fields with 1324 1324 | Some (`Bool b) -> Some b 1325 1325 | Some `Null | None -> None 1326 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "fetchTextBodyValues must be a boolean") 1326 + | Some _ -> raise (Jmap_core.Error.Parse_error "fetchTextBodyValues must be a boolean") 1327 1327 in 1328 1328 let fetch_html_body_values = match find_field "fetchHTMLBodyValues" fields with 1329 1329 | Some (`Bool b) -> Some b 1330 1330 | Some `Null | None -> None 1331 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "fetchHTMLBodyValues must be a boolean") 1331 + | Some _ -> raise (Jmap_core.Error.Parse_error "fetchHTMLBodyValues must be a boolean") 1332 1332 in 1333 1333 let fetch_all_body_values = match find_field "fetchAllBodyValues" fields with 1334 1334 | Some (`Bool b) -> Some b 1335 1335 | Some `Null | None -> None 1336 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "fetchAllBodyValues must be a boolean") 1336 + | Some _ -> raise (Jmap_core.Error.Parse_error "fetchAllBodyValues must be a boolean") 1337 1337 in 1338 1338 let max_body_value_bytes = match find_field "maxBodyValueBytes" fields with 1339 - | Some v -> Some (Jmap_core.Jmap_primitives.UnsignedInt.of_json v) 1339 + | Some v -> Some (Jmap_core.Primitives.UnsignedInt.of_json v) 1340 1340 | None -> None 1341 1341 in 1342 1342 { account_id; blob_ids; properties; body_properties; fetch_text_body_values; ··· 1345 1345 (** Parse parse response from JSON. 1346 1346 Test files: test/data/mail/email_parse_response.json *) 1347 1347 let response_of_json json = 1348 - let open Jmap_core.Jmap_parser.Helpers in 1348 + let open Jmap_core.Parser.Helpers in 1349 1349 let fields = expect_object json in 1350 - let account_id = Jmap_core.Jmap_id.of_json (require_field "accountId" fields) in 1350 + let account_id = Jmap_core.Id.of_json (require_field "accountId" fields) in 1351 1351 let parsed = match find_field "parsed" fields with 1352 1352 | Some `Null | None -> None 1353 1353 | Some (`O pairs) -> 1354 1354 Some (List.map (fun (k, v) -> 1355 - (Jmap_core.Jmap_id.of_string k, of_json v) 1355 + (Jmap_core.Id.of_string k, of_json v) 1356 1356 ) pairs) 1357 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "parsed must be an object") 1357 + | Some _ -> raise (Jmap_core.Error.Parse_error "parsed must be an object") 1358 1358 in 1359 1359 let not_parsable = match find_field "notParsable" fields with 1360 - | Some (`A items) -> Some (List.map Jmap_core.Jmap_id.of_json items) 1360 + | Some (`A items) -> Some (List.map Jmap_core.Id.of_json items) 1361 1361 | Some `Null | None -> None 1362 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "notParsable must be an array") 1362 + | Some _ -> raise (Jmap_core.Error.Parse_error "notParsable must be an array") 1363 1363 in 1364 1364 let not_found = match find_field "notFound" fields with 1365 - | Some (`A items) -> Some (List.map Jmap_core.Jmap_id.of_json items) 1365 + | Some (`A items) -> Some (List.map Jmap_core.Id.of_json items) 1366 1366 | Some `Null | None -> None 1367 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "notFound must be an array") 1367 + | Some _ -> raise (Jmap_core.Error.Parse_error "notFound must be an array") 1368 1368 in 1369 1369 { account_id; parsed; not_parsable; not_found } 1370 1370 end
+144 -144
stack/jmap/jmap-mail/jmap_email.mli
··· 42 42 module BodyPart : sig 43 43 type t = { 44 44 part_id : string option; 45 - blob_id : Jmap_id.t option; 46 - size : Jmap_primitives.UnsignedInt.t; 45 + blob_id : Id.t option; 46 + size : Primitives.UnsignedInt.t; 47 47 headers : EmailHeader.t list; 48 48 name : string option; 49 49 type_ : string; ··· 57 57 58 58 (** Accessors *) 59 59 val part_id : t -> string option 60 - val blob_id : t -> Jmap_id.t option 61 - val size : t -> Jmap_primitives.UnsignedInt.t 60 + val blob_id : t -> Id.t option 61 + val size : t -> Primitives.UnsignedInt.t 62 62 val headers : t -> EmailHeader.t list 63 63 val name : t -> string option 64 64 val type_ : t -> string ··· 72 72 (** Constructor *) 73 73 val v : 74 74 ?part_id:string -> 75 - ?blob_id:Jmap_id.t -> 76 - size:Jmap_primitives.UnsignedInt.t -> 75 + ?blob_id:Id.t -> 76 + size:Primitives.UnsignedInt.t -> 77 77 headers:EmailHeader.t list -> 78 78 ?name:string -> 79 79 type_:string -> ··· 112 112 113 113 (** Email object type (RFC 8621 Section 4.1) *) 114 114 type t = { 115 - id : Jmap_id.t; 116 - blob_id : Jmap_id.t; 117 - thread_id : Jmap_id.t; 118 - mailbox_ids : (Jmap_id.t * bool) list; 115 + id : Id.t; 116 + blob_id : Id.t; 117 + thread_id : Id.t; 118 + mailbox_ids : (Id.t * bool) list; 119 119 keywords : (string * bool) list; 120 - size : Jmap_primitives.UnsignedInt.t; 121 - received_at : Jmap_primitives.UTCDate.t; 120 + size : Primitives.UnsignedInt.t; 121 + received_at : Primitives.UTCDate.t; 122 122 message_id : string list option; 123 123 in_reply_to : string list option; 124 124 references : string list option; ··· 129 129 bcc : EmailAddress.t list option; 130 130 reply_to : EmailAddress.t list option; 131 131 subject : string option; 132 - sent_at : Jmap_primitives.Date.t option; 132 + sent_at : Primitives.Date.t option; 133 133 body_structure : BodyPart.t option; 134 134 body_values : (string * BodyValue.t) list option; 135 135 text_body : BodyPart.t list option; ··· 140 140 } 141 141 142 142 (** Accessors *) 143 - val id : t -> Jmap_id.t 144 - val blob_id : t -> Jmap_id.t 145 - val thread_id : t -> Jmap_id.t 146 - val mailbox_ids : t -> (Jmap_id.t * bool) list 143 + val id : t -> Id.t 144 + val blob_id : t -> Id.t 145 + val thread_id : t -> Id.t 146 + val mailbox_ids : t -> (Id.t * bool) list 147 147 val keywords : t -> (string * bool) list 148 - val size : t -> Jmap_primitives.UnsignedInt.t 149 - val received_at : t -> Jmap_primitives.UTCDate.t 148 + val size : t -> Primitives.UnsignedInt.t 149 + val received_at : t -> Primitives.UTCDate.t 150 150 val message_id : t -> string list option 151 151 val in_reply_to : t -> string list option 152 152 val references : t -> string list option ··· 157 157 val bcc : t -> EmailAddress.t list option 158 158 val reply_to : t -> EmailAddress.t list option 159 159 val subject : t -> string option 160 - val sent_at : t -> Jmap_primitives.Date.t option 160 + val sent_at : t -> Primitives.Date.t option 161 161 val body_structure : t -> BodyPart.t option 162 162 val body_values : t -> (string * BodyValue.t) list option 163 163 val text_body : t -> BodyPart.t list option ··· 168 168 169 169 (** Constructor *) 170 170 val v : 171 - id:Jmap_id.t -> 172 - blob_id:Jmap_id.t -> 173 - thread_id:Jmap_id.t -> 174 - mailbox_ids:(Jmap_id.t * bool) list -> 171 + id:Id.t -> 172 + blob_id:Id.t -> 173 + thread_id:Id.t -> 174 + mailbox_ids:(Id.t * bool) list -> 175 175 keywords:(string * bool) list -> 176 - size:Jmap_primitives.UnsignedInt.t -> 177 - received_at:Jmap_primitives.UTCDate.t -> 176 + size:Primitives.UnsignedInt.t -> 177 + received_at:Primitives.UTCDate.t -> 178 178 ?message_id:string list -> 179 179 ?in_reply_to:string list -> 180 180 ?references:string list -> ··· 185 185 ?bcc:EmailAddress.t list -> 186 186 ?reply_to:EmailAddress.t list -> 187 187 ?subject:string -> 188 - ?sent_at:Jmap_primitives.Date.t -> 188 + ?sent_at:Primitives.Date.t -> 189 189 ?body_structure:BodyPart.t -> 190 190 ?body_values:(string * BodyValue.t) list -> 191 191 ?text_body:BodyPart.t list -> ··· 199 199 (** Email-specific filter for /query *) 200 200 module Filter : sig 201 201 type t = { 202 - in_mailbox : Jmap_id.t option; 203 - in_mailbox_other_than : Jmap_id.t list option; 204 - before : Jmap_primitives.UTCDate.t option; 205 - after : Jmap_primitives.UTCDate.t option; 206 - min_size : Jmap_primitives.UnsignedInt.t option; 207 - max_size : Jmap_primitives.UnsignedInt.t option; 202 + in_mailbox : Id.t option; 203 + in_mailbox_other_than : Id.t list option; 204 + before : Primitives.UTCDate.t option; 205 + after : Primitives.UTCDate.t option; 206 + min_size : Primitives.UnsignedInt.t option; 207 + max_size : Primitives.UnsignedInt.t option; 208 208 all_in_thread_have_keyword : string option; 209 209 some_in_thread_have_keyword : string option; 210 210 none_in_thread_have_keyword : string option; ··· 222 222 } 223 223 224 224 (** Accessors *) 225 - val in_mailbox : t -> Jmap_id.t option 226 - val in_mailbox_other_than : t -> Jmap_id.t list option 227 - val before : t -> Jmap_primitives.UTCDate.t option 228 - val after : t -> Jmap_primitives.UTCDate.t option 229 - val min_size : t -> Jmap_primitives.UnsignedInt.t option 230 - val max_size : t -> Jmap_primitives.UnsignedInt.t option 225 + val in_mailbox : t -> Id.t option 226 + val in_mailbox_other_than : t -> Id.t list option 227 + val before : t -> Primitives.UTCDate.t option 228 + val after : t -> Primitives.UTCDate.t option 229 + val min_size : t -> Primitives.UnsignedInt.t option 230 + val max_size : t -> Primitives.UnsignedInt.t option 231 231 val all_in_thread_have_keyword : t -> string option 232 232 val some_in_thread_have_keyword : t -> string option 233 233 val none_in_thread_have_keyword : t -> string option ··· 245 245 246 246 (** Constructor *) 247 247 val v : 248 - ?in_mailbox:Jmap_id.t -> 249 - ?in_mailbox_other_than:Jmap_id.t list -> 250 - ?before:Jmap_primitives.UTCDate.t -> 251 - ?after:Jmap_primitives.UTCDate.t -> 252 - ?min_size:Jmap_primitives.UnsignedInt.t -> 253 - ?max_size:Jmap_primitives.UnsignedInt.t -> 248 + ?in_mailbox:Id.t -> 249 + ?in_mailbox_other_than:Id.t list -> 250 + ?before:Primitives.UTCDate.t -> 251 + ?after:Primitives.UTCDate.t -> 252 + ?min_size:Primitives.UnsignedInt.t -> 253 + ?max_size:Primitives.UnsignedInt.t -> 254 254 ?all_in_thread_have_keyword:string -> 255 255 ?some_in_thread_have_keyword:string -> 256 256 ?none_in_thread_have_keyword:string -> ··· 275 275 (** Standard /get method *) 276 276 module Get : sig 277 277 type request = { 278 - account_id : Jmap_id.t; 279 - ids : Jmap_id.t list option; 278 + account_id : Id.t; 279 + ids : Id.t list option; 280 280 properties : string list option; 281 281 body_properties : string list option; 282 282 fetch_text_body_values : bool option; 283 283 fetch_html_body_values : bool option; 284 284 fetch_all_body_values : bool option; 285 - max_body_value_bytes : Jmap_primitives.UnsignedInt.t option; 285 + max_body_value_bytes : Primitives.UnsignedInt.t option; 286 286 } 287 287 288 - type response = t Jmap_standard_methods.Get.response 288 + type response = t Standard_methods.Get.response 289 289 290 290 (** Accessors for request *) 291 - val account_id : request -> Jmap_id.t 292 - val ids : request -> Jmap_id.t list option 291 + val account_id : request -> Id.t 292 + val ids : request -> Id.t list option 293 293 val properties : request -> string list option 294 294 val body_properties : request -> string list option 295 295 val fetch_text_body_values : request -> bool option 296 296 val fetch_html_body_values : request -> bool option 297 297 val fetch_all_body_values : request -> bool option 298 - val max_body_value_bytes : request -> Jmap_primitives.UnsignedInt.t option 298 + val max_body_value_bytes : request -> Primitives.UnsignedInt.t option 299 299 300 300 (** Constructor for request *) 301 301 val request_v : 302 - account_id:Jmap_id.t -> 303 - ?ids:Jmap_id.t list -> 302 + account_id:Id.t -> 303 + ?ids:Id.t list -> 304 304 ?properties:string list -> 305 305 ?body_properties:string list -> 306 306 ?fetch_text_body_values:bool -> 307 307 ?fetch_html_body_values:bool -> 308 308 ?fetch_all_body_values:bool -> 309 - ?max_body_value_bytes:Jmap_primitives.UnsignedInt.t -> 309 + ?max_body_value_bytes:Primitives.UnsignedInt.t -> 310 310 unit -> 311 311 request 312 312 ··· 317 317 318 318 (** Standard /changes method *) 319 319 module Changes : sig 320 - type request = Jmap_standard_methods.Changes.request 321 - type response = Jmap_standard_methods.Changes.response 320 + type request = Standard_methods.Changes.request 321 + type response = Standard_methods.Changes.response 322 322 323 323 val request_of_json : Ezjsonm.value -> request 324 324 val response_of_json : Ezjsonm.value -> response ··· 327 327 (** Standard /query method *) 328 328 module Query : sig 329 329 type request = { 330 - account_id : Jmap_id.t; 331 - filter : Filter.t Jmap_filter.t option; 332 - sort : Jmap_comparator.t list option; 333 - position : Jmap_primitives.Int53.t option; 334 - anchor : Jmap_id.t option; 335 - anchor_offset : Jmap_primitives.Int53.t option; 336 - limit : Jmap_primitives.UnsignedInt.t option; 330 + account_id : Id.t; 331 + filter : Filter.t Jmap_core.Filter.t option; 332 + sort : Comparator.t list option; 333 + position : Primitives.Int53.t option; 334 + anchor : Id.t option; 335 + anchor_offset : Primitives.Int53.t option; 336 + limit : Primitives.UnsignedInt.t option; 337 337 calculate_total : bool option; 338 338 collapse_threads : bool option; 339 339 } 340 340 341 - type response = Jmap_standard_methods.Query.response 341 + type response = Standard_methods.Query.response 342 342 343 343 (** Accessors for request *) 344 - val account_id : request -> Jmap_id.t 345 - val filter : request -> Filter.t Jmap_filter.t option 346 - val sort : request -> Jmap_comparator.t list option 347 - val position : request -> Jmap_primitives.Int53.t option 348 - val anchor : request -> Jmap_id.t option 349 - val anchor_offset : request -> Jmap_primitives.Int53.t option 350 - val limit : request -> Jmap_primitives.UnsignedInt.t option 344 + val account_id : request -> Id.t 345 + val filter : request -> Filter.t Jmap_core.Filter.t option 346 + val sort : request -> Comparator.t list option 347 + val position : request -> Primitives.Int53.t option 348 + val anchor : request -> Id.t option 349 + val anchor_offset : request -> Primitives.Int53.t option 350 + val limit : request -> Primitives.UnsignedInt.t option 351 351 val calculate_total : request -> bool option 352 352 val collapse_threads : request -> bool option 353 353 354 354 (** Constructor for request *) 355 355 val request_v : 356 - account_id:Jmap_id.t -> 357 - ?filter:Filter.t Jmap_filter.t -> 358 - ?sort:Jmap_comparator.t list -> 359 - ?position:Jmap_primitives.Int53.t -> 360 - ?anchor:Jmap_id.t -> 361 - ?anchor_offset:Jmap_primitives.Int53.t -> 362 - ?limit:Jmap_primitives.UnsignedInt.t -> 356 + account_id:Id.t -> 357 + ?filter:Filter.t Jmap_core.Filter.t -> 358 + ?sort:Comparator.t list -> 359 + ?position:Primitives.Int53.t -> 360 + ?anchor:Id.t -> 361 + ?anchor_offset:Primitives.Int53.t -> 362 + ?limit:Primitives.UnsignedInt.t -> 363 363 ?calculate_total:bool -> 364 364 ?collapse_threads:bool -> 365 365 unit -> ··· 373 373 (** Standard /queryChanges method *) 374 374 module QueryChanges : sig 375 375 type request = { 376 - account_id : Jmap_id.t; 377 - filter : Filter.t Jmap_filter.t option; 378 - sort : Jmap_comparator.t list option; 376 + account_id : Id.t; 377 + filter : Filter.t Jmap_core.Filter.t option; 378 + sort : Comparator.t list option; 379 379 since_query_state : string; 380 - max_changes : Jmap_primitives.UnsignedInt.t option; 381 - up_to_id : Jmap_id.t option; 380 + max_changes : Primitives.UnsignedInt.t option; 381 + up_to_id : Id.t option; 382 382 calculate_total : bool option; 383 383 collapse_threads : bool option; 384 384 } 385 385 386 - type response = Jmap_standard_methods.QueryChanges.response 386 + type response = Standard_methods.QueryChanges.response 387 387 388 388 (** Accessors for request *) 389 - val account_id : request -> Jmap_id.t 390 - val filter : request -> Filter.t Jmap_filter.t option 391 - val sort : request -> Jmap_comparator.t list option 389 + val account_id : request -> Id.t 390 + val filter : request -> Filter.t Jmap_core.Filter.t option 391 + val sort : request -> Comparator.t list option 392 392 val since_query_state : request -> string 393 - val max_changes : request -> Jmap_primitives.UnsignedInt.t option 394 - val up_to_id : request -> Jmap_id.t option 393 + val max_changes : request -> Primitives.UnsignedInt.t option 394 + val up_to_id : request -> Id.t option 395 395 val calculate_total : request -> bool option 396 396 val collapse_threads : request -> bool option 397 397 398 398 (** Constructor for request *) 399 399 val request_v : 400 - account_id:Jmap_id.t -> 401 - ?filter:Filter.t Jmap_filter.t -> 402 - ?sort:Jmap_comparator.t list -> 400 + account_id:Id.t -> 401 + ?filter:Filter.t Jmap_core.Filter.t -> 402 + ?sort:Comparator.t list -> 403 403 since_query_state:string -> 404 - ?max_changes:Jmap_primitives.UnsignedInt.t -> 405 - ?up_to_id:Jmap_id.t -> 404 + ?max_changes:Primitives.UnsignedInt.t -> 405 + ?up_to_id:Id.t -> 406 406 ?calculate_total:bool -> 407 407 ?collapse_threads:bool -> 408 408 unit -> ··· 414 414 415 415 (** Standard /set method *) 416 416 module Set : sig 417 - type request = t Jmap_standard_methods.Set.request 418 - type response = t Jmap_standard_methods.Set.response 417 + type request = t Standard_methods.Set.request 418 + type response = t Standard_methods.Set.response 419 419 420 420 val request_of_json : Ezjsonm.value -> request 421 421 val response_of_json : Ezjsonm.value -> response ··· 423 423 424 424 (** Standard /copy method *) 425 425 module Copy : sig 426 - type request = t Jmap_standard_methods.Copy.request 427 - type response = t Jmap_standard_methods.Copy.response 426 + type request = t Standard_methods.Copy.request 427 + type response = t Standard_methods.Copy.response 428 428 429 429 val request_of_json : Ezjsonm.value -> request 430 430 val response_of_json : Ezjsonm.value -> response ··· 434 434 module Import : sig 435 435 (** Email import request object *) 436 436 type import_email = { 437 - blob_id : Jmap_id.t; 438 - mailbox_ids : (Jmap_id.t * bool) list; 437 + blob_id : Id.t; 438 + mailbox_ids : (Id.t * bool) list; 439 439 keywords : (string * bool) list; 440 - received_at : Jmap_primitives.UTCDate.t option; 440 + received_at : Primitives.UTCDate.t option; 441 441 } 442 442 443 443 type request = { 444 - account_id : Jmap_id.t; 444 + account_id : Id.t; 445 445 if_in_state : string option; 446 - emails : (Jmap_id.t * import_email) list; 446 + emails : (Id.t * import_email) list; 447 447 } 448 448 449 449 type response = { 450 - account_id : Jmap_id.t; 450 + account_id : Id.t; 451 451 old_state : string option; 452 452 new_state : string; 453 - created : (Jmap_id.t * t) list option; 454 - not_created : (Jmap_id.t * Jmap_error.set_error_detail) list option; 453 + created : (Id.t * t) list option; 454 + not_created : (Id.t * Error.set_error_detail) list option; 455 455 } 456 456 457 457 (** Accessors for import_email *) 458 - val import_blob_id : import_email -> Jmap_id.t 459 - val import_mailbox_ids : import_email -> (Jmap_id.t * bool) list 458 + val import_blob_id : import_email -> Id.t 459 + val import_mailbox_ids : import_email -> (Id.t * bool) list 460 460 val import_keywords : import_email -> (string * bool) list 461 - val import_received_at : import_email -> Jmap_primitives.UTCDate.t option 461 + val import_received_at : import_email -> Primitives.UTCDate.t option 462 462 463 463 (** Constructor for import_email *) 464 464 val import_email_v : 465 - blob_id:Jmap_id.t -> 466 - mailbox_ids:(Jmap_id.t * bool) list -> 465 + blob_id:Id.t -> 466 + mailbox_ids:(Id.t * bool) list -> 467 467 keywords:(string * bool) list -> 468 - ?received_at:Jmap_primitives.UTCDate.t -> 468 + ?received_at:Primitives.UTCDate.t -> 469 469 unit -> 470 470 import_email 471 471 472 472 (** Accessors for request *) 473 - val account_id : request -> Jmap_id.t 473 + val account_id : request -> Id.t 474 474 val if_in_state : request -> string option 475 - val emails : request -> (Jmap_id.t * import_email) list 475 + val emails : request -> (Id.t * import_email) list 476 476 477 477 (** Constructor for request *) 478 478 val request_v : 479 - account_id:Jmap_id.t -> 479 + account_id:Id.t -> 480 480 ?if_in_state:string -> 481 - emails:(Jmap_id.t * import_email) list -> 481 + emails:(Id.t * import_email) list -> 482 482 unit -> 483 483 request 484 484 485 485 (** Accessors for response *) 486 - val response_account_id : response -> Jmap_id.t 486 + val response_account_id : response -> Id.t 487 487 val old_state : response -> string option 488 488 val new_state : response -> string 489 - val created : response -> (Jmap_id.t * t) list option 490 - val not_created : response -> (Jmap_id.t * Jmap_error.set_error_detail) list option 489 + val created : response -> (Id.t * t) list option 490 + val not_created : response -> (Id.t * Error.set_error_detail) list option 491 491 492 492 (** Constructor for response *) 493 493 val response_v : 494 - account_id:Jmap_id.t -> 494 + account_id:Id.t -> 495 495 ?old_state:string -> 496 496 new_state:string -> 497 - ?created:(Jmap_id.t * t) list -> 498 - ?not_created:(Jmap_id.t * Jmap_error.set_error_detail) list -> 497 + ?created:(Id.t * t) list -> 498 + ?not_created:(Id.t * Error.set_error_detail) list -> 499 499 unit -> 500 500 response 501 501 ··· 506 506 (** Email/parse method *) 507 507 module Parse : sig 508 508 type request = { 509 - account_id : Jmap_id.t; 510 - blob_ids : Jmap_id.t list; 509 + account_id : Id.t; 510 + blob_ids : Id.t list; 511 511 properties : string list option; 512 512 body_properties : string list option; 513 513 fetch_text_body_values : bool option; 514 514 fetch_html_body_values : bool option; 515 515 fetch_all_body_values : bool option; 516 - max_body_value_bytes : Jmap_primitives.UnsignedInt.t option; 516 + max_body_value_bytes : Primitives.UnsignedInt.t option; 517 517 } 518 518 519 519 type response = { 520 - account_id : Jmap_id.t; 521 - parsed : (Jmap_id.t * t) list option; 522 - not_parsable : Jmap_id.t list option; 523 - not_found : Jmap_id.t list option; 520 + account_id : Id.t; 521 + parsed : (Id.t * t) list option; 522 + not_parsable : Id.t list option; 523 + not_found : Id.t list option; 524 524 } 525 525 526 526 (** Accessors for request *) 527 - val account_id : request -> Jmap_id.t 528 - val blob_ids : request -> Jmap_id.t list 527 + val account_id : request -> Id.t 528 + val blob_ids : request -> Id.t list 529 529 val properties : request -> string list option 530 530 val body_properties : request -> string list option 531 531 val fetch_text_body_values : request -> bool option 532 532 val fetch_html_body_values : request -> bool option 533 533 val fetch_all_body_values : request -> bool option 534 - val max_body_value_bytes : request -> Jmap_primitives.UnsignedInt.t option 534 + val max_body_value_bytes : request -> Primitives.UnsignedInt.t option 535 535 536 536 (** Constructor for request *) 537 537 val request_v : 538 - account_id:Jmap_id.t -> 539 - blob_ids:Jmap_id.t list -> 538 + account_id:Id.t -> 539 + blob_ids:Id.t list -> 540 540 ?properties:string list -> 541 541 ?body_properties:string list -> 542 542 ?fetch_text_body_values:bool -> 543 543 ?fetch_html_body_values:bool -> 544 544 ?fetch_all_body_values:bool -> 545 - ?max_body_value_bytes:Jmap_primitives.UnsignedInt.t -> 545 + ?max_body_value_bytes:Primitives.UnsignedInt.t -> 546 546 unit -> 547 547 request 548 548 549 549 (** Accessors for response *) 550 - val response_account_id : response -> Jmap_id.t 551 - val parsed : response -> (Jmap_id.t * t) list option 552 - val not_parsable : response -> Jmap_id.t list option 553 - val not_found : response -> Jmap_id.t list option 550 + val response_account_id : response -> Id.t 551 + val parsed : response -> (Id.t * t) list option 552 + val not_parsable : response -> Id.t list option 553 + val not_found : response -> Id.t list option 554 554 555 555 (** Constructor for response *) 556 556 val response_v : 557 - account_id:Jmap_id.t -> 558 - ?parsed:(Jmap_id.t * t) list -> 559 - ?not_parsable:Jmap_id.t list -> 560 - ?not_found:Jmap_id.t list -> 557 + account_id:Id.t -> 558 + ?parsed:(Id.t * t) list -> 559 + ?not_parsable:Id.t list -> 560 + ?not_found:Id.t list -> 561 561 unit -> 562 562 response 563 563
+47 -47
stack/jmap/jmap-mail/jmap_email_submission.ml
··· 36 36 } 37 37 *) 38 38 let of_json _json = 39 - raise (Jmap_core.Jmap_error.Parse_error "Address.of_json not yet implemented") 39 + raise (Jmap_core.Error.Parse_error "Address.of_json not yet implemented") 40 40 41 41 let to_json _t = 42 - raise (Jmap_core.Jmap_error.Parse_error "Address.to_json not yet implemented") 42 + raise (Jmap_core.Error.Parse_error "Address.to_json not yet implemented") 43 43 end 44 44 45 45 (** SMTP Envelope (RFC 8621 Section 7.1.1) *) ··· 74 74 } 75 75 *) 76 76 let of_json _json = 77 - raise (Jmap_core.Jmap_error.Parse_error "Envelope.of_json not yet implemented") 77 + raise (Jmap_core.Error.Parse_error "Envelope.of_json not yet implemented") 78 78 79 79 let to_json _t = 80 - raise (Jmap_core.Jmap_error.Parse_error "Envelope.to_json not yet implemented") 80 + raise (Jmap_core.Error.Parse_error "Envelope.to_json not yet implemented") 81 81 end 82 82 83 83 (** Delivery status for a single recipient (RFC 8621 Section 7.1.4) *) ··· 119 119 } 120 120 *) 121 121 let of_json _json = 122 - raise (Jmap_core.Jmap_error.Parse_error "DeliveryStatus.of_json not yet implemented") 122 + raise (Jmap_core.Error.Parse_error "DeliveryStatus.of_json not yet implemented") 123 123 124 124 let to_json _t = 125 - raise (Jmap_core.Jmap_error.Parse_error "DeliveryStatus.to_json not yet implemented") 125 + raise (Jmap_core.Error.Parse_error "DeliveryStatus.to_json not yet implemented") 126 126 127 127 let delivered_of_string = function 128 128 | "queued" -> Queued ··· 155 155 156 156 (** EmailSubmission object type (RFC 8621 Section 7.1) *) 157 157 type t = { 158 - id : Jmap_core.Jmap_id.t; (** Immutable server-assigned id *) 159 - identity_id : Jmap_core.Jmap_id.t; (** Identity to send from *) 160 - email_id : Jmap_core.Jmap_id.t; (** Email to send *) 161 - thread_id : Jmap_core.Jmap_id.t; (** Thread ID of email *) 158 + id : Jmap_core.Id.t; (** Immutable server-assigned id *) 159 + identity_id : Jmap_core.Id.t; (** Identity to send from *) 160 + email_id : Jmap_core.Id.t; (** Email to send *) 161 + thread_id : Jmap_core.Id.t; (** Thread ID of email *) 162 162 envelope : Envelope.t option; (** SMTP envelope (null = derive from headers) *) 163 - send_at : Jmap_core.Jmap_primitives.UTCDate.t; (** When to send (may be in future) *) 163 + send_at : Jmap_core.Primitives.UTCDate.t; (** When to send (may be in future) *) 164 164 undo_status : undo_status; (** Whether message can be cancelled *) 165 165 delivery_status : (string * DeliveryStatus.t) list option; (** Map of email to delivery status *) 166 - dsn_blob_ids : Jmap_core.Jmap_id.t list; (** Blob IDs of received DSN messages *) 167 - mdn_blob_ids : Jmap_core.Jmap_id.t list; (** Blob IDs of received MDN messages *) 166 + dsn_blob_ids : Jmap_core.Id.t list; (** Blob IDs of received DSN messages *) 167 + mdn_blob_ids : Jmap_core.Id.t list; (** Blob IDs of received MDN messages *) 168 168 } 169 169 170 170 (** Accessors *) ··· 185 185 186 186 (** Standard /get method (RFC 8621 Section 7.2) *) 187 187 module Get = struct 188 - type request = t Jmap_core.Jmap_standard_methods.Get.request 189 - type response = t Jmap_core.Jmap_standard_methods.Get.response 188 + type request = t Jmap_core.Standard_methods.Get.request 189 + type response = t Jmap_core.Standard_methods.Get.response 190 190 191 191 (** Parse get request from JSON. 192 192 Test files: test/data/mail/email_submission_get_request.json ··· 198 198 } 199 199 *) 200 200 let request_of_json _json = 201 - raise (Jmap_core.Jmap_error.Parse_error "EmailSubmission.Get.request_of_json not yet implemented") 201 + raise (Jmap_core.Error.Parse_error "EmailSubmission.Get.request_of_json not yet implemented") 202 202 203 203 (** Parse get response from JSON. 204 204 Test files: test/data/mail/email_submission_get_response.json ··· 225 225 } 226 226 *) 227 227 let response_of_json _json = 228 - raise (Jmap_core.Jmap_error.Parse_error "EmailSubmission.Get.response_of_json not yet implemented") 228 + raise (Jmap_core.Error.Parse_error "EmailSubmission.Get.response_of_json not yet implemented") 229 229 end 230 230 231 231 (** Standard /changes method (RFC 8621 Section 7.3) *) 232 232 module Changes = struct 233 - type request = Jmap_core.Jmap_standard_methods.Changes.request 234 - type response = Jmap_core.Jmap_standard_methods.Changes.response 233 + type request = Jmap_core.Standard_methods.Changes.request 234 + type response = Jmap_core.Standard_methods.Changes.response 235 235 236 236 let request_of_json _json = 237 - raise (Jmap_core.Jmap_error.Parse_error "EmailSubmission.Changes.request_of_json not yet implemented") 237 + raise (Jmap_core.Error.Parse_error "EmailSubmission.Changes.request_of_json not yet implemented") 238 238 239 239 let response_of_json _json = 240 - raise (Jmap_core.Jmap_error.Parse_error "EmailSubmission.Changes.response_of_json not yet implemented") 240 + raise (Jmap_core.Error.Parse_error "EmailSubmission.Changes.response_of_json not yet implemented") 241 241 end 242 242 243 243 (** EmailSubmission-specific filter for /query (RFC 8621 Section 7.5) *) 244 244 module Filter = struct 245 245 type t = { 246 - identity_ids : Jmap_core.Jmap_id.t list option; (** Submission uses one of these identities *) 247 - email_ids : Jmap_core.Jmap_id.t list option; (** Submission is for one of these emails *) 248 - thread_ids : Jmap_core.Jmap_id.t list option; (** Submission is for email in one of these threads *) 246 + identity_ids : Jmap_core.Id.t list option; (** Submission uses one of these identities *) 247 + email_ids : Jmap_core.Id.t list option; (** Submission is for one of these emails *) 248 + thread_ids : Jmap_core.Id.t list option; (** Submission is for email in one of these threads *) 249 249 undo_status : undo_status option; (** undoStatus equals this *) 250 - before : Jmap_core.Jmap_primitives.UTCDate.t option; (** sendAt < this *) 251 - after : Jmap_core.Jmap_primitives.UTCDate.t option; (** sendAt >= this *) 250 + before : Jmap_core.Primitives.UTCDate.t option; (** sendAt < this *) 251 + after : Jmap_core.Primitives.UTCDate.t option; (** sendAt >= this *) 252 252 } 253 253 254 254 (** Accessors *) ··· 264 264 { identity_ids; email_ids; thread_ids; undo_status; before; after } 265 265 266 266 let of_json _json = 267 - raise (Jmap_core.Jmap_error.Parse_error "EmailSubmission.Filter.of_json not yet implemented") 267 + raise (Jmap_core.Error.Parse_error "EmailSubmission.Filter.of_json not yet implemented") 268 268 end 269 269 270 270 (** Standard /query method (RFC 8621 Section 7.5) *) 271 271 module Query = struct 272 - type request = Filter.t Jmap_core.Jmap_standard_methods.Query.request 273 - type response = Jmap_core.Jmap_standard_methods.Query.response 272 + type request = Filter.t Jmap_core.Standard_methods.Query.request 273 + type response = Jmap_core.Standard_methods.Query.response 274 274 275 275 let request_of_json _json = 276 - raise (Jmap_core.Jmap_error.Parse_error "EmailSubmission.Query.request_of_json not yet implemented") 276 + raise (Jmap_core.Error.Parse_error "EmailSubmission.Query.request_of_json not yet implemented") 277 277 278 278 let response_of_json _json = 279 - raise (Jmap_core.Jmap_error.Parse_error "EmailSubmission.Query.response_of_json not yet implemented") 279 + raise (Jmap_core.Error.Parse_error "EmailSubmission.Query.response_of_json not yet implemented") 280 280 end 281 281 282 282 (** Standard /queryChanges method (RFC 8621 Section 7.6) *) 283 283 module QueryChanges = struct 284 - type request = Filter.t Jmap_core.Jmap_standard_methods.QueryChanges.request 285 - type response = Jmap_core.Jmap_standard_methods.QueryChanges.response 284 + type request = Filter.t Jmap_core.Standard_methods.QueryChanges.request 285 + type response = Jmap_core.Standard_methods.QueryChanges.response 286 286 287 287 let request_of_json _json = 288 - raise (Jmap_core.Jmap_error.Parse_error "EmailSubmission.QueryChanges.request_of_json not yet implemented") 288 + raise (Jmap_core.Error.Parse_error "EmailSubmission.QueryChanges.request_of_json not yet implemented") 289 289 290 290 let response_of_json _json = 291 - raise (Jmap_core.Jmap_error.Parse_error "EmailSubmission.QueryChanges.response_of_json not yet implemented") 291 + raise (Jmap_core.Error.Parse_error "EmailSubmission.QueryChanges.response_of_json not yet implemented") 292 292 end 293 293 294 294 (** Standard /set method (RFC 8621 Section 7.4) ··· 301 301 module Set = struct 302 302 (** On success action for EmailSubmission/set create *) 303 303 type on_success = { 304 - set_email_keywords : (Jmap_core.Jmap_id.t * (string * bool) list) option; (** Set keywords on sent email *) 304 + set_email_keywords : (Jmap_core.Id.t * (string * bool) list) option; (** Set keywords on sent email *) 305 305 } 306 306 307 307 type request = { 308 - account_id : Jmap_core.Jmap_id.t; 308 + account_id : Jmap_core.Id.t; 309 309 if_in_state : string option; 310 - create : (Jmap_core.Jmap_id.t * t) list option; 311 - update : (Jmap_core.Jmap_id.t * Jmap_core.Jmap_standard_methods.Set.patch_object) list option; 312 - destroy : Jmap_core.Jmap_id.t list option; 310 + create : (Jmap_core.Id.t * t) list option; 311 + update : (Jmap_core.Id.t * Jmap_core.Standard_methods.Set.patch_object) list option; 312 + destroy : Jmap_core.Id.t list option; 313 313 (* EmailSubmission-specific *) 314 - on_success_update_email : (Jmap_core.Jmap_id.t * on_success) list option; (** Actions to perform on success *) 315 - on_success_destroy_email : Jmap_core.Jmap_id.t list option; (** Email IDs to destroy on success *) 314 + on_success_update_email : (Jmap_core.Id.t * on_success) list option; (** Actions to perform on success *) 315 + on_success_destroy_email : Jmap_core.Id.t list option; (** Email IDs to destroy on success *) 316 316 } 317 317 318 - type response = t Jmap_core.Jmap_standard_methods.Set.response 318 + type response = t Jmap_core.Standard_methods.Set.response 319 319 320 320 (** Accessors for on_success *) 321 321 let on_success_set_email_keywords os = os.set_email_keywords ··· 340 340 on_success_update_email; on_success_destroy_email } 341 341 342 342 let request_of_json _json = 343 - raise (Jmap_core.Jmap_error.Parse_error "EmailSubmission.Set.request_of_json not yet implemented") 343 + raise (Jmap_core.Error.Parse_error "EmailSubmission.Set.request_of_json not yet implemented") 344 344 345 345 let response_of_json _json = 346 - raise (Jmap_core.Jmap_error.Parse_error "EmailSubmission.Set.response_of_json not yet implemented") 346 + raise (Jmap_core.Error.Parse_error "EmailSubmission.Set.response_of_json not yet implemented") 347 347 end 348 348 349 349 (** Parser submodule *) ··· 376 376 *) 377 377 let of_json _json = 378 378 (* TODO: Implement JSON parsing *) 379 - raise (Jmap_core.Jmap_error.Parse_error "EmailSubmission.Parser.of_json not yet implemented") 379 + raise (Jmap_core.Error.Parse_error "EmailSubmission.Parser.of_json not yet implemented") 380 380 381 381 let to_json _t = 382 382 (* TODO: Implement JSON serialization *) 383 - raise (Jmap_core.Jmap_error.Parse_error "EmailSubmission.Parser.to_json not yet implemented") 383 + raise (Jmap_core.Error.Parse_error "EmailSubmission.Parser.to_json not yet implemented") 384 384 end 385 385 386 386 (** Helper functions for undo_status *)
+66 -66
stack/jmap/jmap-mail/jmap_email_submission.mli
··· 83 83 84 84 (** EmailSubmission object type (RFC 8621 Section 7.1) *) 85 85 type t = { 86 - id : Jmap_id.t; 87 - identity_id : Jmap_id.t; 88 - email_id : Jmap_id.t; 89 - thread_id : Jmap_id.t; 86 + id : Id.t; 87 + identity_id : Id.t; 88 + email_id : Id.t; 89 + thread_id : Id.t; 90 90 envelope : Envelope.t option; 91 - send_at : Jmap_primitives.UTCDate.t; 91 + send_at : Primitives.UTCDate.t; 92 92 undo_status : undo_status; 93 93 delivery_status : (string * DeliveryStatus.t) list option; 94 - dsn_blob_ids : Jmap_id.t list; 95 - mdn_blob_ids : Jmap_id.t list; 94 + dsn_blob_ids : Id.t list; 95 + mdn_blob_ids : Id.t list; 96 96 } 97 97 98 98 (** Accessors *) 99 - val id : t -> Jmap_id.t 100 - val identity_id : t -> Jmap_id.t 101 - val email_id : t -> Jmap_id.t 102 - val thread_id : t -> Jmap_id.t 99 + val id : t -> Id.t 100 + val identity_id : t -> Id.t 101 + val email_id : t -> Id.t 102 + val thread_id : t -> Id.t 103 103 val envelope : t -> Envelope.t option 104 - val send_at : t -> Jmap_primitives.UTCDate.t 104 + val send_at : t -> Primitives.UTCDate.t 105 105 val undo_status : t -> undo_status 106 106 val delivery_status : t -> (string * DeliveryStatus.t) list option 107 - val dsn_blob_ids : t -> Jmap_id.t list 108 - val mdn_blob_ids : t -> Jmap_id.t list 107 + val dsn_blob_ids : t -> Id.t list 108 + val mdn_blob_ids : t -> Id.t list 109 109 110 110 (** Constructor *) 111 111 val v : 112 - id:Jmap_id.t -> 113 - identity_id:Jmap_id.t -> 114 - email_id:Jmap_id.t -> 115 - thread_id:Jmap_id.t -> 112 + id:Id.t -> 113 + identity_id:Id.t -> 114 + email_id:Id.t -> 115 + thread_id:Id.t -> 116 116 ?envelope:Envelope.t -> 117 - send_at:Jmap_primitives.UTCDate.t -> 117 + send_at:Primitives.UTCDate.t -> 118 118 undo_status:undo_status -> 119 119 ?delivery_status:(string * DeliveryStatus.t) list -> 120 - dsn_blob_ids:Jmap_id.t list -> 121 - mdn_blob_ids:Jmap_id.t list -> 120 + dsn_blob_ids:Id.t list -> 121 + mdn_blob_ids:Id.t list -> 122 122 unit -> 123 123 t 124 124 125 125 (** Standard /get method *) 126 126 module Get : sig 127 - type request = t Jmap_standard_methods.Get.request 128 - type response = t Jmap_standard_methods.Get.response 127 + type request = t Standard_methods.Get.request 128 + type response = t Standard_methods.Get.response 129 129 130 130 val request_of_json : Ezjsonm.value -> request 131 131 val response_of_json : Ezjsonm.value -> response ··· 133 133 134 134 (** Standard /changes method *) 135 135 module Changes : sig 136 - type request = Jmap_standard_methods.Changes.request 137 - type response = Jmap_standard_methods.Changes.response 136 + type request = Standard_methods.Changes.request 137 + type response = Standard_methods.Changes.response 138 138 139 139 val request_of_json : Ezjsonm.value -> request 140 140 val response_of_json : Ezjsonm.value -> response ··· 143 143 (** EmailSubmission-specific filter for /query *) 144 144 module Filter : sig 145 145 type t = { 146 - identity_ids : Jmap_id.t list option; 147 - email_ids : Jmap_id.t list option; 148 - thread_ids : Jmap_id.t list option; 146 + identity_ids : Id.t list option; 147 + email_ids : Id.t list option; 148 + thread_ids : Id.t list option; 149 149 undo_status : undo_status option; 150 - before : Jmap_primitives.UTCDate.t option; 151 - after : Jmap_primitives.UTCDate.t option; 150 + before : Primitives.UTCDate.t option; 151 + after : Primitives.UTCDate.t option; 152 152 } 153 153 154 154 (** Accessors *) 155 - val identity_ids : t -> Jmap_id.t list option 156 - val email_ids : t -> Jmap_id.t list option 157 - val thread_ids : t -> Jmap_id.t list option 155 + val identity_ids : t -> Id.t list option 156 + val email_ids : t -> Id.t list option 157 + val thread_ids : t -> Id.t list option 158 158 val undo_status : t -> undo_status option 159 - val before : t -> Jmap_primitives.UTCDate.t option 160 - val after : t -> Jmap_primitives.UTCDate.t option 159 + val before : t -> Primitives.UTCDate.t option 160 + val after : t -> Primitives.UTCDate.t option 161 161 162 162 (** Constructor *) 163 163 val v : 164 - ?identity_ids:Jmap_id.t list -> 165 - ?email_ids:Jmap_id.t list -> 166 - ?thread_ids:Jmap_id.t list -> 164 + ?identity_ids:Id.t list -> 165 + ?email_ids:Id.t list -> 166 + ?thread_ids:Id.t list -> 167 167 ?undo_status:undo_status -> 168 - ?before:Jmap_primitives.UTCDate.t -> 169 - ?after:Jmap_primitives.UTCDate.t -> 168 + ?before:Primitives.UTCDate.t -> 169 + ?after:Primitives.UTCDate.t -> 170 170 unit -> 171 171 t 172 172 ··· 175 175 176 176 (** Standard /query method *) 177 177 module Query : sig 178 - type request = Filter.t Jmap_standard_methods.Query.request 179 - type response = Jmap_standard_methods.Query.response 178 + type request = Filter.t Standard_methods.Query.request 179 + type response = Standard_methods.Query.response 180 180 181 181 val request_of_json : Ezjsonm.value -> request 182 182 val response_of_json : Ezjsonm.value -> response ··· 184 184 185 185 (** Standard /queryChanges method *) 186 186 module QueryChanges : sig 187 - type request = Filter.t Jmap_standard_methods.QueryChanges.request 188 - type response = Jmap_standard_methods.QueryChanges.response 187 + type request = Filter.t Standard_methods.QueryChanges.request 188 + type response = Standard_methods.QueryChanges.response 189 189 190 190 val request_of_json : Ezjsonm.value -> request 191 191 val response_of_json : Ezjsonm.value -> response ··· 195 195 module Set : sig 196 196 (** On success action for EmailSubmission/set create *) 197 197 type on_success = { 198 - set_email_keywords : (Jmap_id.t * (string * bool) list) option; 198 + set_email_keywords : (Id.t * (string * bool) list) option; 199 199 } 200 200 201 201 type request = { 202 - account_id : Jmap_id.t; 202 + account_id : Id.t; 203 203 if_in_state : string option; 204 - create : (Jmap_id.t * t) list option; 205 - update : (Jmap_id.t * Jmap_standard_methods.Set.patch_object) list option; 206 - destroy : Jmap_id.t list option; 207 - on_success_update_email : (Jmap_id.t * on_success) list option; 208 - on_success_destroy_email : Jmap_id.t list option; 204 + create : (Id.t * t) list option; 205 + update : (Id.t * Standard_methods.Set.patch_object) list option; 206 + destroy : Id.t list option; 207 + on_success_update_email : (Id.t * on_success) list option; 208 + on_success_destroy_email : Id.t list option; 209 209 } 210 210 211 - type response = t Jmap_standard_methods.Set.response 211 + type response = t Standard_methods.Set.response 212 212 213 213 (** Accessors for on_success *) 214 - val on_success_set_email_keywords : on_success -> (Jmap_id.t * (string * bool) list) option 214 + val on_success_set_email_keywords : on_success -> (Id.t * (string * bool) list) option 215 215 216 216 (** Constructor for on_success *) 217 217 val on_success_v : 218 - ?set_email_keywords:(Jmap_id.t * (string * bool) list) -> 218 + ?set_email_keywords:(Id.t * (string * bool) list) -> 219 219 unit -> 220 220 on_success 221 221 222 222 (** Accessors for request *) 223 - val account_id : request -> Jmap_id.t 223 + val account_id : request -> Id.t 224 224 val if_in_state : request -> string option 225 - val create : request -> (Jmap_id.t * t) list option 226 - val update : request -> (Jmap_id.t * Jmap_standard_methods.Set.patch_object) list option 227 - val destroy : request -> Jmap_id.t list option 228 - val on_success_update_email : request -> (Jmap_id.t * on_success) list option 229 - val on_success_destroy_email : request -> Jmap_id.t list option 225 + val create : request -> (Id.t * t) list option 226 + val update : request -> (Id.t * Standard_methods.Set.patch_object) list option 227 + val destroy : request -> Id.t list option 228 + val on_success_update_email : request -> (Id.t * on_success) list option 229 + val on_success_destroy_email : request -> Id.t list option 230 230 231 231 (** Constructor for request *) 232 232 val request_v : 233 - account_id:Jmap_id.t -> 233 + account_id:Id.t -> 234 234 ?if_in_state:string -> 235 - ?create:(Jmap_id.t * t) list -> 236 - ?update:(Jmap_id.t * Jmap_standard_methods.Set.patch_object) list -> 237 - ?destroy:Jmap_id.t list -> 238 - ?on_success_update_email:(Jmap_id.t * on_success) list -> 239 - ?on_success_destroy_email:Jmap_id.t list -> 235 + ?create:(Id.t * t) list -> 236 + ?update:(Id.t * Standard_methods.Set.patch_object) list -> 237 + ?destroy:Id.t list -> 238 + ?on_success_update_email:(Id.t * on_success) list -> 239 + ?on_success_destroy_email:Id.t list -> 240 240 unit -> 241 241 request 242 242
+15 -15
stack/jmap/jmap-mail/jmap_identity.ml
··· 14 14 15 15 (** Identity object type (RFC 8621 Section 6.1) *) 16 16 type t = { 17 - id : Jmap_core.Jmap_id.t; (** Immutable server-assigned id *) 17 + id : Jmap_core.Id.t; (** Immutable server-assigned id *) 18 18 name : string; (** Display name for this identity (e.g., "Alice Jones") *) 19 19 email : string; (** Email address (e.g., "alice@example.com") *) 20 20 reply_to : Jmap_email.EmailAddress.t list option; (** Reply-To addresses to use *) ··· 45 45 controls which identities exist based on account configuration. 46 46 *) 47 47 module Get = struct 48 - type request = t Jmap_core.Jmap_standard_methods.Get.request 49 - type response = t Jmap_core.Jmap_standard_methods.Get.response 48 + type request = t Jmap_core.Standard_methods.Get.request 49 + type response = t Jmap_core.Standard_methods.Get.response 50 50 51 51 (** Parse get request from JSON. 52 52 Test files: test/data/mail/identity_get_request.json ··· 58 58 } 59 59 *) 60 60 let request_of_json _json = 61 - raise (Jmap_core.Jmap_error.Parse_error "Identity.Get.request_of_json not yet implemented") 61 + raise (Jmap_core.Error.Parse_error "Identity.Get.request_of_json not yet implemented") 62 62 63 63 (** Parse get response from JSON. 64 64 Test files: test/data/mail/identity_get_response.json ··· 83 83 } 84 84 *) 85 85 let response_of_json _json = 86 - raise (Jmap_core.Jmap_error.Parse_error "Identity.Get.response_of_json not yet implemented") 86 + raise (Jmap_core.Error.Parse_error "Identity.Get.response_of_json not yet implemented") 87 87 end 88 88 89 89 (** Standard /changes method (RFC 8621 Section 6.3) *) 90 90 module Changes = struct 91 - type request = Jmap_core.Jmap_standard_methods.Changes.request 92 - type response = Jmap_core.Jmap_standard_methods.Changes.response 91 + type request = Jmap_core.Standard_methods.Changes.request 92 + type response = Jmap_core.Standard_methods.Changes.response 93 93 94 94 let request_of_json _json = 95 - raise (Jmap_core.Jmap_error.Parse_error "Identity.Changes.request_of_json not yet implemented") 95 + raise (Jmap_core.Error.Parse_error "Identity.Changes.request_of_json not yet implemented") 96 96 97 97 let response_of_json _json = 98 - raise (Jmap_core.Jmap_error.Parse_error "Identity.Changes.response_of_json not yet implemented") 98 + raise (Jmap_core.Error.Parse_error "Identity.Changes.response_of_json not yet implemented") 99 99 end 100 100 101 101 (** Standard /set method (RFC 8621 Section 6.4) ··· 105 105 are derived from server/account configuration. 106 106 *) 107 107 module Set = struct 108 - type request = t Jmap_core.Jmap_standard_methods.Set.request 109 - type response = t Jmap_core.Jmap_standard_methods.Set.response 108 + type request = t Jmap_core.Standard_methods.Set.request 109 + type response = t Jmap_core.Standard_methods.Set.response 110 110 111 111 let request_of_json _json = 112 - raise (Jmap_core.Jmap_error.Parse_error "Identity.Set.request_of_json not yet implemented") 112 + raise (Jmap_core.Error.Parse_error "Identity.Set.request_of_json not yet implemented") 113 113 114 114 let response_of_json _json = 115 - raise (Jmap_core.Jmap_error.Parse_error "Identity.Set.response_of_json not yet implemented") 115 + raise (Jmap_core.Error.Parse_error "Identity.Set.response_of_json not yet implemented") 116 116 end 117 117 118 118 (** Parser submodule *) ··· 134 134 *) 135 135 let of_json _json = 136 136 (* TODO: Implement JSON parsing *) 137 - raise (Jmap_core.Jmap_error.Parse_error "Identity.Parser.of_json not yet implemented") 137 + raise (Jmap_core.Error.Parse_error "Identity.Parser.of_json not yet implemented") 138 138 139 139 let to_json _t = 140 140 (* TODO: Implement JSON serialization *) 141 - raise (Jmap_core.Jmap_error.Parse_error "Identity.Parser.to_json not yet implemented") 141 + raise (Jmap_core.Error.Parse_error "Identity.Parser.to_json not yet implemented") 142 142 end
+9 -9
stack/jmap/jmap-mail/jmap_identity.mli
··· 4 4 5 5 (** Identity object type (RFC 8621 Section 6.1) *) 6 6 type t = { 7 - id : Jmap_id.t; 7 + id : Id.t; 8 8 name : string; 9 9 email : string; 10 10 reply_to : Jmap_email.EmailAddress.t list option; ··· 15 15 } 16 16 17 17 (** Accessors *) 18 - val id : t -> Jmap_id.t 18 + val id : t -> Id.t 19 19 val name : t -> string 20 20 val email : t -> string 21 21 val reply_to : t -> Jmap_email.EmailAddress.t list option ··· 26 26 27 27 (** Constructor *) 28 28 val v : 29 - id:Jmap_id.t -> 29 + id:Id.t -> 30 30 name:string -> 31 31 email:string -> 32 32 ?reply_to:Jmap_email.EmailAddress.t list -> ··· 39 39 40 40 (** Standard /get method *) 41 41 module Get : sig 42 - type request = t Jmap_standard_methods.Get.request 43 - type response = t Jmap_standard_methods.Get.response 42 + type request = t Standard_methods.Get.request 43 + type response = t Standard_methods.Get.response 44 44 45 45 val request_of_json : Ezjsonm.value -> request 46 46 val response_of_json : Ezjsonm.value -> response ··· 48 48 49 49 (** Standard /changes method *) 50 50 module Changes : sig 51 - type request = Jmap_standard_methods.Changes.request 52 - type response = Jmap_standard_methods.Changes.response 51 + type request = Standard_methods.Changes.request 52 + type response = Standard_methods.Changes.response 53 53 54 54 val request_of_json : Ezjsonm.value -> request 55 55 val response_of_json : Ezjsonm.value -> response ··· 57 57 58 58 (** Standard /set method *) 59 59 module Set : sig 60 - type request = t Jmap_standard_methods.Set.request 61 - type response = t Jmap_standard_methods.Set.response 60 + type request = t Standard_methods.Set.request 61 + type response = t Standard_methods.Set.response 62 62 63 63 val request_of_json : Ezjsonm.value -> request 64 64 val response_of_json : Ezjsonm.value -> response
-11
stack/jmap/jmap-mail/jmap_mail.ml
··· 1 1 (** JMAP Mail Extension Library *) 2 2 3 - (** Re-export all submodules *) 4 3 module Mailbox = Jmap_mailbox 5 4 module Thread = Jmap_thread 6 5 module Email = Jmap_email ··· 9 8 module Vacation_response = Jmap_vacation_response 10 9 module Search_snippet = Jmap_search_snippet 11 10 module Mail_parser = Jmap_mail_parser 12 - 13 - (** For backwards compatibility *) 14 - module Jmap_mailbox = Jmap_mailbox 15 - module Jmap_thread = Jmap_thread 16 - module Jmap_email = Jmap_email 17 - module Jmap_identity = Jmap_identity 18 - module Jmap_email_submission = Jmap_email_submission 19 - module Jmap_vacation_response = Jmap_vacation_response 20 - module Jmap_search_snippet = Jmap_search_snippet 21 - module Jmap_mail_parser = Jmap_mail_parser
+8 -9
stack/jmap/jmap-mail/jmap_mail.mli
··· 1 1 (** JMAP Mail Extension Library *) 2 2 3 - (** Re-export all submodules *) 4 - module Jmap_mailbox = Jmap_mailbox 5 - module Jmap_thread = Jmap_thread 6 - module Jmap_email = Jmap_email 7 - module Jmap_identity = Jmap_identity 8 - module Jmap_email_submission = Jmap_email_submission 9 - module Jmap_vacation_response = Jmap_vacation_response 10 - module Jmap_search_snippet = Jmap_search_snippet 11 - module Jmap_mail_parser = Jmap_mail_parser 3 + module Mailbox = Jmap_mailbox 4 + module Thread = Jmap_thread 5 + module Email = Jmap_email 6 + module Identity = Jmap_identity 7 + module Email_submission = Jmap_email_submission 8 + module Vacation_response = Jmap_vacation_response 9 + module Search_snippet = Jmap_search_snippet 10 + module Mail_parser = Jmap_mail_parser
+65 -65
stack/jmap/jmap-mail/jmap_mailbox.ml
··· 46 46 } 47 47 *) 48 48 let of_json json = 49 - let open Jmap_core.Jmap_parser.Helpers in 49 + let open Jmap_core.Parser.Helpers in 50 50 let fields = expect_object json in 51 51 { 52 52 may_read_items = get_bool "mayReadItems" fields; ··· 93 93 94 94 (** Mailbox object type *) 95 95 type t = { 96 - id : Jmap_core.Jmap_id.t; (** Immutable server-assigned id *) 96 + id : Jmap_core.Id.t; (** Immutable server-assigned id *) 97 97 name : string; (** User-visible mailbox name *) 98 - parent_id : Jmap_core.Jmap_id.t option; (** Parent mailbox id (null for top-level) *) 98 + parent_id : Jmap_core.Id.t option; (** Parent mailbox id (null for top-level) *) 99 99 role : string option; (** Standard role (inbox, trash, sent, etc.) *) 100 - sort_order : Jmap_core.Jmap_primitives.UnsignedInt.t; (** Sort order for display *) 101 - total_emails : Jmap_core.Jmap_primitives.UnsignedInt.t; (** Total number of emails in mailbox *) 102 - unread_emails : Jmap_core.Jmap_primitives.UnsignedInt.t; (** Number of emails without $seen keyword *) 103 - total_threads : Jmap_core.Jmap_primitives.UnsignedInt.t; (** Total number of threads with emails in mailbox *) 104 - unread_threads : Jmap_core.Jmap_primitives.UnsignedInt.t; (** Number of threads with unread emails in mailbox *) 100 + sort_order : Jmap_core.Primitives.UnsignedInt.t; (** Sort order for display *) 101 + total_emails : Jmap_core.Primitives.UnsignedInt.t; (** Total number of emails in mailbox *) 102 + unread_emails : Jmap_core.Primitives.UnsignedInt.t; (** Number of emails without $seen keyword *) 103 + total_threads : Jmap_core.Primitives.UnsignedInt.t; (** Total number of threads with emails in mailbox *) 104 + unread_threads : Jmap_core.Primitives.UnsignedInt.t; (** Number of threads with unread emails in mailbox *) 105 105 my_rights : Rights.t; (** Current user's access rights *) 106 106 is_subscribed : bool; (** Whether user is subscribed to this mailbox *) 107 107 } ··· 146 146 } 147 147 *) 148 148 let of_json json = 149 - let open Jmap_core.Jmap_parser.Helpers in 149 + let open Jmap_core.Parser.Helpers in 150 150 let fields = expect_object json in 151 - let id = Jmap_core.Jmap_id.of_json (require_field "id" fields) in 151 + let id = Jmap_core.Id.of_json (require_field "id" fields) in 152 152 let name = get_string "name" fields in 153 153 let parent_id = match find_field "parentId" fields with 154 154 | Some `Null | None -> None 155 - | Some v -> Some (Jmap_core.Jmap_id.of_json v) 155 + | Some v -> Some (Jmap_core.Id.of_json v) 156 156 in 157 157 let role = match find_field "role" fields with 158 158 | Some `Null | None -> None 159 159 | Some (`String s) -> Some s 160 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "role must be a string or null") 160 + | Some _ -> raise (Jmap_core.Error.Parse_error "role must be a string or null") 161 161 in 162 - let sort_order = Jmap_core.Jmap_primitives.UnsignedInt.of_json (require_field "sortOrder" fields) in 163 - let total_emails = Jmap_core.Jmap_primitives.UnsignedInt.of_json (require_field "totalEmails" fields) in 164 - let unread_emails = Jmap_core.Jmap_primitives.UnsignedInt.of_json (require_field "unreadEmails" fields) in 165 - let total_threads = Jmap_core.Jmap_primitives.UnsignedInt.of_json (require_field "totalThreads" fields) in 166 - let unread_threads = Jmap_core.Jmap_primitives.UnsignedInt.of_json (require_field "unreadThreads" fields) in 162 + let sort_order = Jmap_core.Primitives.UnsignedInt.of_json (require_field "sortOrder" fields) in 163 + let total_emails = Jmap_core.Primitives.UnsignedInt.of_json (require_field "totalEmails" fields) in 164 + let unread_emails = Jmap_core.Primitives.UnsignedInt.of_json (require_field "unreadEmails" fields) in 165 + let total_threads = Jmap_core.Primitives.UnsignedInt.of_json (require_field "totalThreads" fields) in 166 + let unread_threads = Jmap_core.Primitives.UnsignedInt.of_json (require_field "unreadThreads" fields) in 167 167 let my_rights = Rights.of_json (require_field "myRights" fields) in 168 168 let is_subscribed = get_bool "isSubscribed" fields in 169 169 { id; name; parent_id; role; sort_order; total_emails; unread_emails; ··· 171 171 172 172 let to_json t = 173 173 let fields = [ 174 - ("id", Jmap_core.Jmap_id.to_json t.id); 174 + ("id", Jmap_core.Id.to_json t.id); 175 175 ("name", `String t.name); 176 - ("sortOrder", Jmap_core.Jmap_primitives.UnsignedInt.to_json t.sort_order); 177 - ("totalEmails", Jmap_core.Jmap_primitives.UnsignedInt.to_json t.total_emails); 178 - ("unreadEmails", Jmap_core.Jmap_primitives.UnsignedInt.to_json t.unread_emails); 179 - ("totalThreads", Jmap_core.Jmap_primitives.UnsignedInt.to_json t.total_threads); 180 - ("unreadThreads", Jmap_core.Jmap_primitives.UnsignedInt.to_json t.unread_threads); 176 + ("sortOrder", Jmap_core.Primitives.UnsignedInt.to_json t.sort_order); 177 + ("totalEmails", Jmap_core.Primitives.UnsignedInt.to_json t.total_emails); 178 + ("unreadEmails", Jmap_core.Primitives.UnsignedInt.to_json t.unread_emails); 179 + ("totalThreads", Jmap_core.Primitives.UnsignedInt.to_json t.total_threads); 180 + ("unreadThreads", Jmap_core.Primitives.UnsignedInt.to_json t.unread_threads); 181 181 ("myRights", Rights.to_json t.my_rights); 182 182 ("isSubscribed", `Bool t.is_subscribed); 183 183 ] in 184 184 let fields = match t.parent_id with 185 - | Some pid -> ("parentId", Jmap_core.Jmap_id.to_json pid) :: fields 185 + | Some pid -> ("parentId", Jmap_core.Id.to_json pid) :: fields 186 186 | None -> ("parentId", `Null) :: fields 187 187 in 188 188 let fields = match t.role with ··· 194 194 195 195 (** Standard /get method (RFC 8621 Section 2.2) *) 196 196 module Get = struct 197 - type request = t Jmap_core.Jmap_standard_methods.Get.request 198 - type response = t Jmap_core.Jmap_standard_methods.Get.response 197 + type request = t Jmap_core.Standard_methods.Get.request 198 + type response = t Jmap_core.Standard_methods.Get.response 199 199 200 200 (** Parse get request from JSON *) 201 201 let request_of_json json = 202 - Jmap_core.Jmap_standard_methods.Get.request_of_json Parser.of_json json 202 + Jmap_core.Standard_methods.Get.request_of_json Parser.of_json json 203 203 204 204 (** Parse get response from JSON *) 205 205 let response_of_json json = 206 - Jmap_core.Jmap_standard_methods.Get.response_of_json Parser.of_json json 206 + Jmap_core.Standard_methods.Get.response_of_json Parser.of_json json 207 207 end 208 208 209 209 (** Standard /changes method (RFC 8621 Section 2.3) *) 210 210 module Changes = struct 211 - type request = Jmap_core.Jmap_standard_methods.Changes.request 212 - type response = Jmap_core.Jmap_standard_methods.Changes.response 211 + type request = Jmap_core.Standard_methods.Changes.request 212 + type response = Jmap_core.Standard_methods.Changes.response 213 213 214 214 let request_of_json json = 215 - Jmap_core.Jmap_standard_methods.Changes.request_of_json json 215 + Jmap_core.Standard_methods.Changes.request_of_json json 216 216 217 217 let response_of_json json = 218 - Jmap_core.Jmap_standard_methods.Changes.response_of_json json 218 + Jmap_core.Standard_methods.Changes.response_of_json json 219 219 end 220 220 221 221 (** Mailbox-specific filter for /query (RFC 8621 Section 2.5) *) 222 222 module Filter = struct 223 223 type t = { 224 - parent_id : Jmap_core.Jmap_id.t option; (** Mailbox parentId equals this value *) 224 + parent_id : Jmap_core.Id.t option; (** Mailbox parentId equals this value *) 225 225 name : string option; (** Name contains this string (case-insensitive) *) 226 226 role : string option; (** Role equals this value *) 227 227 has_any_role : bool option; (** Has any role assigned (true) or no role (false) *) ··· 229 229 } 230 230 231 231 let of_json json = 232 - let open Jmap_core.Jmap_parser.Helpers in 232 + let open Jmap_core.Parser.Helpers in 233 233 let fields = expect_object json in 234 234 let parent_id = match find_field "parentId" fields with 235 235 | Some `Null -> Some None (* Explicitly filter for null parent *) 236 - | Some v -> Some (Some (Jmap_core.Jmap_id.of_json v)) 236 + | Some v -> Some (Some (Jmap_core.Id.of_json v)) 237 237 | None -> None (* Don't filter on parentId *) 238 238 in 239 239 let name = get_string_opt "name" fields in 240 240 let role = get_string_opt "role" fields in 241 241 let has_any_role = match find_field "hasAnyRole" fields with 242 242 | Some (`Bool b) -> Some b 243 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "hasAnyRole must be a boolean") 243 + | Some _ -> raise (Jmap_core.Error.Parse_error "hasAnyRole must be a boolean") 244 244 | None -> None 245 245 in 246 246 let is_subscribed = match find_field "isSubscribed" fields with 247 247 | Some (`Bool b) -> Some b 248 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "isSubscribed must be a boolean") 248 + | Some _ -> raise (Jmap_core.Error.Parse_error "isSubscribed must be a boolean") 249 249 | None -> None 250 250 in 251 251 (* Note: parent_id has special handling - None means don't filter, ··· 271 271 (** Standard /query method with Mailbox-specific extensions (RFC 8621 Section 2.5) *) 272 272 module Query = struct 273 273 type request = { 274 - account_id : Jmap_core.Jmap_id.t; 275 - filter : Filter.t Jmap_core.Jmap_filter.t option; 276 - sort : Jmap_core.Jmap_comparator.t list option; 277 - position : Jmap_core.Jmap_primitives.Int53.t option; 278 - anchor : Jmap_core.Jmap_id.t option; 279 - anchor_offset : Jmap_core.Jmap_primitives.Int53.t option; 280 - limit : Jmap_core.Jmap_primitives.UnsignedInt.t option; 274 + account_id : Jmap_core.Id.t; 275 + filter : Filter.t Jmap_core.Filter.t option; 276 + sort : Jmap_core.Comparator.t list option; 277 + position : Jmap_core.Primitives.Int53.t option; 278 + anchor : Jmap_core.Id.t option; 279 + anchor_offset : Jmap_core.Primitives.Int53.t option; 280 + limit : Jmap_core.Primitives.UnsignedInt.t option; 281 281 calculate_total : bool option; 282 282 (* Mailbox-specific query arguments *) 283 283 sort_as_tree : bool option; (** Return results in tree order *) 284 284 filter_as_tree : bool option; (** If true, apply filter to tree roots and return descendants *) 285 285 } 286 286 287 - type response = Jmap_core.Jmap_standard_methods.Query.response 287 + type response = Jmap_core.Standard_methods.Query.response 288 288 289 289 (* Accessors for request *) 290 290 let account_id req = req.account_id ··· 307 307 (** Parse query request from JSON. 308 308 Test files: test/data/mail/mailbox_query_request.json *) 309 309 let request_of_json json = 310 - let open Jmap_core.Jmap_parser.Helpers in 310 + let open Jmap_core.Parser.Helpers in 311 311 let fields = expect_object json in 312 - let account_id = Jmap_core.Jmap_id.of_json (require_field "accountId" fields) in 312 + let account_id = Jmap_core.Id.of_json (require_field "accountId" fields) in 313 313 let filter = match find_field "filter" fields with 314 - | Some v -> Some (Jmap_core.Jmap_filter.of_json Filter.of_json v) 314 + | Some v -> Some (Jmap_core.Filter.of_json Filter.of_json v) 315 315 | None -> None 316 316 in 317 317 let sort = match find_field "sort" fields with 318 - | Some v -> Some (parse_array Jmap_core.Jmap_comparator.of_json v) 318 + | Some v -> Some (parse_array Jmap_core.Comparator.of_json v) 319 319 | None -> None 320 320 in 321 321 let position = match find_field "position" fields with 322 - | Some v -> Some (Jmap_core.Jmap_primitives.Int53.of_json v) 322 + | Some v -> Some (Jmap_core.Primitives.Int53.of_json v) 323 323 | None -> None 324 324 in 325 325 let anchor = match find_field "anchor" fields with 326 - | Some v -> Some (Jmap_core.Jmap_id.of_json v) 326 + | Some v -> Some (Jmap_core.Id.of_json v) 327 327 | None -> None 328 328 in 329 329 let anchor_offset = match find_field "anchorOffset" fields with 330 - | Some v -> Some (Jmap_core.Jmap_primitives.Int53.of_json v) 330 + | Some v -> Some (Jmap_core.Primitives.Int53.of_json v) 331 331 | None -> None 332 332 in 333 333 let limit = match find_field "limit" fields with 334 - | Some v -> Some (Jmap_core.Jmap_primitives.UnsignedInt.of_json v) 334 + | Some v -> Some (Jmap_core.Primitives.UnsignedInt.of_json v) 335 335 | None -> None 336 336 in 337 337 let calculate_total = match find_field "calculateTotal" fields with 338 338 | Some (`Bool b) -> Some b 339 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "calculateTotal must be a boolean") 339 + | Some _ -> raise (Jmap_core.Error.Parse_error "calculateTotal must be a boolean") 340 340 | None -> None 341 341 in 342 342 let sort_as_tree = match find_field "sortAsTree" fields with 343 343 | Some (`Bool b) -> Some b 344 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "sortAsTree must be a boolean") 344 + | Some _ -> raise (Jmap_core.Error.Parse_error "sortAsTree must be a boolean") 345 345 | None -> None 346 346 in 347 347 let filter_as_tree = match find_field "filterAsTree" fields with 348 348 | Some (`Bool b) -> Some b 349 - | Some _ -> raise (Jmap_core.Jmap_error.Parse_error "filterAsTree must be a boolean") 349 + | Some _ -> raise (Jmap_core.Error.Parse_error "filterAsTree must be a boolean") 350 350 | None -> None 351 351 in 352 352 { account_id; filter; sort; position; anchor; anchor_offset; limit; ··· 355 355 (** Parse query response from JSON. 356 356 Test files: test/data/mail/mailbox_query_response.json *) 357 357 let response_of_json json = 358 - Jmap_core.Jmap_standard_methods.Query.response_of_json json 358 + Jmap_core.Standard_methods.Query.response_of_json json 359 359 end 360 360 361 361 (** Standard /queryChanges method (RFC 8621 Section 2.6) *) 362 362 module QueryChanges = struct 363 - type request = Filter.t Jmap_core.Jmap_standard_methods.QueryChanges.request 364 - type response = Jmap_core.Jmap_standard_methods.QueryChanges.response 363 + type request = Filter.t Jmap_core.Standard_methods.QueryChanges.request 364 + type response = Jmap_core.Standard_methods.QueryChanges.response 365 365 366 366 let request_of_json json = 367 - Jmap_core.Jmap_standard_methods.QueryChanges.request_of_json Filter.of_json json 367 + Jmap_core.Standard_methods.QueryChanges.request_of_json Filter.of_json json 368 368 369 369 let response_of_json json = 370 - Jmap_core.Jmap_standard_methods.QueryChanges.response_of_json json 370 + Jmap_core.Standard_methods.QueryChanges.response_of_json json 371 371 end 372 372 373 373 (** Standard /set method (RFC 8621 Section 2.4) *) 374 374 module Set = struct 375 - type request = t Jmap_core.Jmap_standard_methods.Set.request 376 - type response = t Jmap_core.Jmap_standard_methods.Set.response 375 + type request = t Jmap_core.Standard_methods.Set.request 376 + type response = t Jmap_core.Standard_methods.Set.response 377 377 378 378 (** Parse set request from JSON. 379 379 Test files: test/data/mail/mailbox_set_request.json *) 380 380 let request_of_json json = 381 - Jmap_core.Jmap_standard_methods.Set.request_of_json Parser.of_json json 381 + Jmap_core.Standard_methods.Set.request_of_json Parser.of_json json 382 382 383 383 (** Parse set response from JSON. 384 384 Test files: test/data/mail/mailbox_set_response.json *) 385 385 let response_of_json json = 386 - Jmap_core.Jmap_standard_methods.Set.response_of_json Parser.of_json json 386 + Jmap_core.Standard_methods.Set.response_of_json Parser.of_json json 387 387 end 388 388 389 389 (** Standard mailbox role values (RFC 8621 Section 2.1) *)
+54 -54
stack/jmap/jmap-mail/jmap_mailbox.mli
··· 46 46 47 47 (** Mailbox object type *) 48 48 type t = { 49 - id : Jmap_id.t; 49 + id : Id.t; 50 50 name : string; 51 - parent_id : Jmap_id.t option; 51 + parent_id : Id.t option; 52 52 role : string option; 53 - sort_order : Jmap_primitives.UnsignedInt.t; 54 - total_emails : Jmap_primitives.UnsignedInt.t; 55 - unread_emails : Jmap_primitives.UnsignedInt.t; 56 - total_threads : Jmap_primitives.UnsignedInt.t; 57 - unread_threads : Jmap_primitives.UnsignedInt.t; 53 + sort_order : Primitives.UnsignedInt.t; 54 + total_emails : Primitives.UnsignedInt.t; 55 + unread_emails : Primitives.UnsignedInt.t; 56 + total_threads : Primitives.UnsignedInt.t; 57 + unread_threads : Primitives.UnsignedInt.t; 58 58 my_rights : Rights.t; 59 59 is_subscribed : bool; 60 60 } 61 61 62 62 (** Accessors *) 63 - val id : t -> Jmap_id.t 63 + val id : t -> Id.t 64 64 val name : t -> string 65 - val parent_id : t -> Jmap_id.t option 65 + val parent_id : t -> Id.t option 66 66 val role : t -> string option 67 - val sort_order : t -> Jmap_primitives.UnsignedInt.t 68 - val total_emails : t -> Jmap_primitives.UnsignedInt.t 69 - val unread_emails : t -> Jmap_primitives.UnsignedInt.t 70 - val total_threads : t -> Jmap_primitives.UnsignedInt.t 71 - val unread_threads : t -> Jmap_primitives.UnsignedInt.t 67 + val sort_order : t -> Primitives.UnsignedInt.t 68 + val total_emails : t -> Primitives.UnsignedInt.t 69 + val unread_emails : t -> Primitives.UnsignedInt.t 70 + val total_threads : t -> Primitives.UnsignedInt.t 71 + val unread_threads : t -> Primitives.UnsignedInt.t 72 72 val my_rights : t -> Rights.t 73 73 val is_subscribed : t -> bool 74 74 75 75 (** Constructor *) 76 76 val v : 77 - id:Jmap_id.t -> 77 + id:Id.t -> 78 78 name:string -> 79 - ?parent_id:Jmap_id.t -> 79 + ?parent_id:Id.t -> 80 80 ?role:string -> 81 - sort_order:Jmap_primitives.UnsignedInt.t -> 82 - total_emails:Jmap_primitives.UnsignedInt.t -> 83 - unread_emails:Jmap_primitives.UnsignedInt.t -> 84 - total_threads:Jmap_primitives.UnsignedInt.t -> 85 - unread_threads:Jmap_primitives.UnsignedInt.t -> 81 + sort_order:Primitives.UnsignedInt.t -> 82 + total_emails:Primitives.UnsignedInt.t -> 83 + unread_emails:Primitives.UnsignedInt.t -> 84 + total_threads:Primitives.UnsignedInt.t -> 85 + unread_threads:Primitives.UnsignedInt.t -> 86 86 my_rights:Rights.t -> 87 87 is_subscribed:bool -> 88 88 unit -> ··· 90 90 91 91 (** Standard /get method *) 92 92 module Get : sig 93 - type request = t Jmap_standard_methods.Get.request 94 - type response = t Jmap_standard_methods.Get.response 93 + type request = t Standard_methods.Get.request 94 + type response = t Standard_methods.Get.response 95 95 96 96 val request_of_json : Ezjsonm.value -> request 97 97 val response_of_json : Ezjsonm.value -> response ··· 99 99 100 100 (** Standard /changes method *) 101 101 module Changes : sig 102 - type request = Jmap_standard_methods.Changes.request 103 - type response = Jmap_standard_methods.Changes.response 102 + type request = Standard_methods.Changes.request 103 + type response = Standard_methods.Changes.response 104 104 105 105 val request_of_json : Ezjsonm.value -> request 106 106 val response_of_json : Ezjsonm.value -> response ··· 109 109 (** Mailbox-specific filter for /query *) 110 110 module Filter : sig 111 111 type t = { 112 - parent_id : Jmap_id.t option; 112 + parent_id : Id.t option; 113 113 name : string option; 114 114 role : string option; 115 115 has_any_role : bool option; ··· 117 117 } 118 118 119 119 (** Accessors *) 120 - val parent_id : t -> Jmap_id.t option 120 + val parent_id : t -> Id.t option 121 121 val name : t -> string option 122 122 val role : t -> string option 123 123 val has_any_role : t -> bool option ··· 125 125 126 126 (** Constructor *) 127 127 val v : 128 - ?parent_id:Jmap_id.t -> 128 + ?parent_id:Id.t -> 129 129 ?name:string -> 130 130 ?role:string -> 131 131 ?has_any_role:bool -> ··· 139 139 (** Standard /query method with Mailbox-specific extensions *) 140 140 module Query : sig 141 141 type request = { 142 - account_id : Jmap_id.t; 143 - filter : Filter.t Jmap_filter.t option; 144 - sort : Jmap_comparator.t list option; 145 - position : Jmap_primitives.Int53.t option; 146 - anchor : Jmap_id.t option; 147 - anchor_offset : Jmap_primitives.Int53.t option; 148 - limit : Jmap_primitives.UnsignedInt.t option; 142 + account_id : Id.t; 143 + filter : Filter.t Jmap_core.Filter.t option; 144 + sort : Comparator.t list option; 145 + position : Primitives.Int53.t option; 146 + anchor : Id.t option; 147 + anchor_offset : Primitives.Int53.t option; 148 + limit : Primitives.UnsignedInt.t option; 149 149 calculate_total : bool option; 150 150 sort_as_tree : bool option; 151 151 filter_as_tree : bool option; 152 152 } 153 153 154 - type response = Jmap_standard_methods.Query.response 154 + type response = Standard_methods.Query.response 155 155 156 156 (** Accessors for request *) 157 - val account_id : request -> Jmap_id.t 158 - val filter : request -> Filter.t Jmap_filter.t option 159 - val sort : request -> Jmap_comparator.t list option 160 - val position : request -> Jmap_primitives.Int53.t option 161 - val anchor : request -> Jmap_id.t option 162 - val anchor_offset : request -> Jmap_primitives.Int53.t option 163 - val limit : request -> Jmap_primitives.UnsignedInt.t option 157 + val account_id : request -> Id.t 158 + val filter : request -> Filter.t Jmap_core.Filter.t option 159 + val sort : request -> Comparator.t list option 160 + val position : request -> Primitives.Int53.t option 161 + val anchor : request -> Id.t option 162 + val anchor_offset : request -> Primitives.Int53.t option 163 + val limit : request -> Primitives.UnsignedInt.t option 164 164 val calculate_total : request -> bool option 165 165 val sort_as_tree : request -> bool option 166 166 val filter_as_tree : request -> bool option 167 167 168 168 (** Constructor for request *) 169 169 val request_v : 170 - account_id:Jmap_id.t -> 171 - ?filter:Filter.t Jmap_filter.t -> 172 - ?sort:Jmap_comparator.t list -> 173 - ?position:Jmap_primitives.Int53.t -> 174 - ?anchor:Jmap_id.t -> 175 - ?anchor_offset:Jmap_primitives.Int53.t -> 176 - ?limit:Jmap_primitives.UnsignedInt.t -> 170 + account_id:Id.t -> 171 + ?filter:Filter.t Jmap_core.Filter.t -> 172 + ?sort:Comparator.t list -> 173 + ?position:Primitives.Int53.t -> 174 + ?anchor:Id.t -> 175 + ?anchor_offset:Primitives.Int53.t -> 176 + ?limit:Primitives.UnsignedInt.t -> 177 177 ?calculate_total:bool -> 178 178 ?sort_as_tree:bool -> 179 179 ?filter_as_tree:bool -> ··· 186 186 187 187 (** Standard /queryChanges method *) 188 188 module QueryChanges : sig 189 - type request = Filter.t Jmap_standard_methods.QueryChanges.request 190 - type response = Jmap_standard_methods.QueryChanges.response 189 + type request = Filter.t Standard_methods.QueryChanges.request 190 + type response = Standard_methods.QueryChanges.response 191 191 192 192 val request_of_json : Ezjsonm.value -> request 193 193 val response_of_json : Ezjsonm.value -> response ··· 195 195 196 196 (** Standard /set method *) 197 197 module Set : sig 198 - type request = t Jmap_standard_methods.Set.request 199 - type response = t Jmap_standard_methods.Set.response 198 + type request = t Standard_methods.Set.request 199 + type response = t Standard_methods.Set.response 200 200 201 201 val request_of_json : Ezjsonm.value -> request 202 202 val response_of_json : Ezjsonm.value -> response
+10 -10
stack/jmap/jmap-mail/jmap_search_snippet.ml
··· 21 21 The <mark> tags indicate where the search terms matched. 22 22 *) 23 23 type t = { 24 - email_id : Jmap_core.Jmap_id.t; (** Email ID this snippet is for *) 24 + email_id : Jmap_core.Id.t; (** Email ID this snippet is for *) 25 25 subject : string option; (** Subject with search terms highlighted using <mark> tags *) 26 26 preview : string option; (** Preview text with search terms highlighted using <mark> tags *) 27 27 } ··· 45 45 *) 46 46 module Get = struct 47 47 type request = { 48 - account_id : Jmap_core.Jmap_id.t; 49 - filter : Jmap_email.Filter.t Jmap_core.Jmap_filter.t; (** Filter to apply for highlighting *) 50 - email_ids : Jmap_core.Jmap_id.t list; (** Email IDs to get snippets for *) 48 + account_id : Jmap_core.Id.t; 49 + filter : Jmap_email.Filter.t Jmap_core.Filter.t; (** Filter to apply for highlighting *) 50 + email_ids : Jmap_core.Id.t list; (** Email IDs to get snippets for *) 51 51 } 52 52 53 53 type response = { 54 - account_id : Jmap_core.Jmap_id.t; 54 + account_id : Jmap_core.Id.t; 55 55 list : t list; (** SearchSnippets for requested emails *) 56 - not_found : Jmap_core.Jmap_id.t list; (** Email IDs that don't exist *) 56 + not_found : Jmap_core.Id.t list; (** Email IDs that don't exist *) 57 57 } 58 58 59 59 (** Accessors for request *) ··· 87 87 } 88 88 *) 89 89 let request_of_json _json = 90 - raise (Jmap_core.Jmap_error.Parse_error "SearchSnippet.Get.request_of_json not yet implemented") 90 + raise (Jmap_core.Error.Parse_error "SearchSnippet.Get.request_of_json not yet implemented") 91 91 92 92 (** Parse get response from JSON. 93 93 Test files: test/data/mail/search_snippet_response.json ··· 106 106 } 107 107 *) 108 108 let response_of_json _json = 109 - raise (Jmap_core.Jmap_error.Parse_error "SearchSnippet.Get.response_of_json not yet implemented") 109 + raise (Jmap_core.Error.Parse_error "SearchSnippet.Get.response_of_json not yet implemented") 110 110 end 111 111 112 112 (** Parser submodule *) ··· 123 123 *) 124 124 let of_json _json = 125 125 (* TODO: Implement JSON parsing *) 126 - raise (Jmap_core.Jmap_error.Parse_error "SearchSnippet.Parser.of_json not yet implemented") 126 + raise (Jmap_core.Error.Parse_error "SearchSnippet.Parser.of_json not yet implemented") 127 127 128 128 let to_json _t = 129 129 (* TODO: Implement JSON serialization *) 130 - raise (Jmap_core.Jmap_error.Parse_error "SearchSnippet.Parser.to_json not yet implemented") 130 + raise (Jmap_core.Error.Parse_error "SearchSnippet.Parser.to_json not yet implemented") 131 131 end
+18 -18
stack/jmap/jmap-mail/jmap_search_snippet.mli
··· 4 4 5 5 (** SearchSnippet object type (RFC 8621 Section 5.1) *) 6 6 type t = { 7 - email_id : Jmap_id.t; 7 + email_id : Id.t; 8 8 subject : string option; 9 9 preview : string option; 10 10 } 11 11 12 12 (** Accessors *) 13 - val email_id : t -> Jmap_id.t 13 + val email_id : t -> Id.t 14 14 val subject : t -> string option 15 15 val preview : t -> string option 16 16 17 17 (** Constructor *) 18 - val v : email_id:Jmap_id.t -> ?subject:string -> ?preview:string -> unit -> t 18 + val v : email_id:Id.t -> ?subject:string -> ?preview:string -> unit -> t 19 19 20 20 (** SearchSnippet/get method *) 21 21 module Get : sig 22 22 type request = { 23 - account_id : Jmap_id.t; 24 - filter : Jmap_email.Filter.t Jmap_filter.t; 25 - email_ids : Jmap_id.t list; 23 + account_id : Id.t; 24 + filter : Jmap_email.Filter.t Filter.t; 25 + email_ids : Id.t list; 26 26 } 27 27 28 28 type response = { 29 - account_id : Jmap_id.t; 29 + account_id : Id.t; 30 30 list : t list; 31 - not_found : Jmap_id.t list; 31 + not_found : Id.t list; 32 32 } 33 33 34 34 (** Accessors for request *) 35 - val account_id : request -> Jmap_id.t 36 - val filter : request -> Jmap_email.Filter.t Jmap_filter.t 37 - val email_ids : request -> Jmap_id.t list 35 + val account_id : request -> Id.t 36 + val filter : request -> Jmap_email.Filter.t Filter.t 37 + val email_ids : request -> Id.t list 38 38 39 39 (** Constructor for request *) 40 40 val request_v : 41 - account_id:Jmap_id.t -> 42 - filter:Jmap_email.Filter.t Jmap_filter.t -> 43 - email_ids:Jmap_id.t list -> 41 + account_id:Id.t -> 42 + filter:Jmap_email.Filter.t Filter.t -> 43 + email_ids:Id.t list -> 44 44 request 45 45 46 46 (** Accessors for response *) 47 - val response_account_id : response -> Jmap_id.t 47 + val response_account_id : response -> Id.t 48 48 val list : response -> t list 49 - val not_found : response -> Jmap_id.t list 49 + val not_found : response -> Id.t list 50 50 51 51 (** Constructor for response *) 52 52 val response_v : 53 - account_id:Jmap_id.t -> 53 + account_id:Id.t -> 54 54 list:t list -> 55 - not_found:Jmap_id.t list -> 55 + not_found:Id.t list -> 56 56 response 57 57 58 58 val request_of_json : Ezjsonm.value -> request
+8 -8
stack/jmap/jmap-mail/jmap_thread.ml
··· 17 17 18 18 (** Thread object type *) 19 19 type t = { 20 - id : Jmap_core.Jmap_id.t; (** Immutable server-assigned thread id *) 21 - email_ids : Jmap_core.Jmap_id.t list; (** List of email ids in this thread, sorted by date (oldest first) *) 20 + id : Jmap_core.Id.t; (** Immutable server-assigned thread id *) 21 + email_ids : Jmap_core.Id.t list; (** List of email ids in this thread, sorted by date (oldest first) *) 22 22 } 23 23 24 24 (** Accessors *) ··· 37 37 - /queryChanges 38 38 *) 39 39 module Get = struct 40 - type request = t Jmap_core.Jmap_standard_methods.Get.request 41 - type response = t Jmap_core.Jmap_standard_methods.Get.response 40 + type request = t Jmap_core.Standard_methods.Get.request 41 + type response = t Jmap_core.Standard_methods.Get.response 42 42 43 43 (** Parse get request from JSON. 44 44 Test files: test/data/mail/thread_get_request.json ··· 50 50 } 51 51 *) 52 52 let request_of_json _json = 53 - raise (Jmap_core.Jmap_error.Parse_error "Thread.Get.request_of_json not yet implemented") 53 + raise (Jmap_core.Error.Parse_error "Thread.Get.request_of_json not yet implemented") 54 54 55 55 (** Parse get response from JSON. 56 56 Test files: test/data/mail/thread_get_response.json ··· 69 69 } 70 70 *) 71 71 let response_of_json _json = 72 - raise (Jmap_core.Jmap_error.Parse_error "Thread.Get.response_of_json not yet implemented") 72 + raise (Jmap_core.Error.Parse_error "Thread.Get.response_of_json not yet implemented") 73 73 end 74 74 75 75 (** Parser submodule *) ··· 85 85 *) 86 86 let of_json _json = 87 87 (* TODO: Implement JSON parsing *) 88 - raise (Jmap_core.Jmap_error.Parse_error "Thread.Parser.of_json not yet implemented") 88 + raise (Jmap_core.Error.Parse_error "Thread.Parser.of_json not yet implemented") 89 89 90 90 let to_json _t = 91 91 (* TODO: Implement JSON serialization *) 92 - raise (Jmap_core.Jmap_error.Parse_error "Thread.Parser.to_json not yet implemented") 92 + raise (Jmap_core.Error.Parse_error "Thread.Parser.to_json not yet implemented") 93 93 end
+7 -7
stack/jmap/jmap-mail/jmap_thread.mli
··· 4 4 5 5 (** Thread object type *) 6 6 type t = { 7 - id : Jmap_id.t; 8 - email_ids : Jmap_id.t list; 7 + id : Id.t; 8 + email_ids : Id.t list; 9 9 } 10 10 11 11 (** Accessors *) 12 - val id : t -> Jmap_id.t 13 - val email_ids : t -> Jmap_id.t list 12 + val id : t -> Id.t 13 + val email_ids : t -> Id.t list 14 14 15 15 (** Constructor *) 16 - val v : id:Jmap_id.t -> email_ids:Jmap_id.t list -> t 16 + val v : id:Id.t -> email_ids:Id.t list -> t 17 17 18 18 (** Standard /get method *) 19 19 module Get : sig 20 - type request = t Jmap_standard_methods.Get.request 21 - type response = t Jmap_standard_methods.Get.response 20 + type request = t Standard_methods.Get.request 21 + type response = t Standard_methods.Get.response 22 22 23 23 val request_of_json : Ezjsonm.value -> request 24 24 val response_of_json : Ezjsonm.value -> response
+13 -13
stack/jmap/jmap-mail/jmap_vacation_response.ml
··· 17 17 with id "singleton". It cannot be created or destroyed, only updated. 18 18 *) 19 19 type t = { 20 - id : Jmap_core.Jmap_id.t; (** Always "singleton" *) 20 + id : Jmap_core.Id.t; (** Always "singleton" *) 21 21 is_enabled : bool; (** Is vacation response currently active? *) 22 - from_date : Jmap_core.Jmap_primitives.UTCDate.t option; (** Start date (null = active now) *) 23 - to_date : Jmap_core.Jmap_primitives.UTCDate.t option; (** End date (null = no end) *) 22 + from_date : Jmap_core.Primitives.UTCDate.t option; (** Start date (null = active now) *) 23 + to_date : Jmap_core.Primitives.UTCDate.t option; (** End date (null = no end) *) 24 24 subject : string option; (** Subject for auto-reply message *) 25 25 text_body : string option; (** Plain text auto-reply body *) 26 26 html_body : string option; (** HTML auto-reply body *) ··· 48 48 } 49 49 *) 50 50 module Get = struct 51 - type request = t Jmap_core.Jmap_standard_methods.Get.request 52 - type response = t Jmap_core.Jmap_standard_methods.Get.response 51 + type request = t Jmap_core.Standard_methods.Get.request 52 + type response = t Jmap_core.Standard_methods.Get.response 53 53 54 54 (** Parse get request from JSON. 55 55 Test files: test/data/mail/vacation_response_get_request.json ··· 61 61 } 62 62 *) 63 63 let request_of_json _json = 64 - raise (Jmap_core.Jmap_error.Parse_error "VacationResponse.Get.request_of_json not yet implemented") 64 + raise (Jmap_core.Error.Parse_error "VacationResponse.Get.request_of_json not yet implemented") 65 65 66 66 (** Parse get response from JSON. 67 67 Test files: test/data/mail/vacation_response_get_response.json ··· 84 84 } 85 85 *) 86 86 let response_of_json _json = 87 - raise (Jmap_core.Jmap_error.Parse_error "VacationResponse.Get.response_of_json not yet implemented") 87 + raise (Jmap_core.Error.Parse_error "VacationResponse.Get.response_of_json not yet implemented") 88 88 end 89 89 90 90 (** Standard /set method (RFC 8621 Section 8.3) ··· 109 109 } 110 110 *) 111 111 module Set = struct 112 - type request = t Jmap_core.Jmap_standard_methods.Set.request 113 - type response = t Jmap_core.Jmap_standard_methods.Set.response 112 + type request = t Jmap_core.Standard_methods.Set.request 113 + type response = t Jmap_core.Standard_methods.Set.response 114 114 115 115 let request_of_json _json = 116 - raise (Jmap_core.Jmap_error.Parse_error "VacationResponse.Set.request_of_json not yet implemented") 116 + raise (Jmap_core.Error.Parse_error "VacationResponse.Set.request_of_json not yet implemented") 117 117 118 118 let response_of_json _json = 119 - raise (Jmap_core.Jmap_error.Parse_error "VacationResponse.Set.response_of_json not yet implemented") 119 + raise (Jmap_core.Error.Parse_error "VacationResponse.Set.response_of_json not yet implemented") 120 120 end 121 121 122 122 (** Parser submodule *) ··· 137 137 *) 138 138 let of_json _json = 139 139 (* TODO: Implement JSON parsing *) 140 - raise (Jmap_core.Jmap_error.Parse_error "VacationResponse.Parser.of_json not yet implemented") 140 + raise (Jmap_core.Error.Parse_error "VacationResponse.Parser.of_json not yet implemented") 141 141 142 142 let to_json _t = 143 143 (* TODO: Implement JSON serialization *) 144 - raise (Jmap_core.Jmap_error.Parse_error "VacationResponse.Parser.to_json not yet implemented") 144 + raise (Jmap_core.Error.Parse_error "VacationResponse.Parser.to_json not yet implemented") 145 145 end 146 146 147 147 (** Singleton ID constant *)
+13 -13
stack/jmap/jmap-mail/jmap_vacation_response.mli
··· 4 4 5 5 (** VacationResponse object type (RFC 8621 Section 8.1) *) 6 6 type t = { 7 - id : Jmap_id.t; 7 + id : Id.t; 8 8 is_enabled : bool; 9 - from_date : Jmap_primitives.UTCDate.t option; 10 - to_date : Jmap_primitives.UTCDate.t option; 9 + from_date : Primitives.UTCDate.t option; 10 + to_date : Primitives.UTCDate.t option; 11 11 subject : string option; 12 12 text_body : string option; 13 13 html_body : string option; 14 14 } 15 15 16 16 (** Accessors *) 17 - val id : t -> Jmap_id.t 17 + val id : t -> Id.t 18 18 val is_enabled : t -> bool 19 - val from_date : t -> Jmap_primitives.UTCDate.t option 20 - val to_date : t -> Jmap_primitives.UTCDate.t option 19 + val from_date : t -> Primitives.UTCDate.t option 20 + val to_date : t -> Primitives.UTCDate.t option 21 21 val subject : t -> string option 22 22 val text_body : t -> string option 23 23 val html_body : t -> string option 24 24 25 25 (** Constructor *) 26 26 val v : 27 - id:Jmap_id.t -> 27 + id:Id.t -> 28 28 is_enabled:bool -> 29 - ?from_date:Jmap_primitives.UTCDate.t -> 30 - ?to_date:Jmap_primitives.UTCDate.t -> 29 + ?from_date:Primitives.UTCDate.t -> 30 + ?to_date:Primitives.UTCDate.t -> 31 31 ?subject:string -> 32 32 ?text_body:string -> 33 33 ?html_body:string -> ··· 36 36 37 37 (** Standard /get method *) 38 38 module Get : sig 39 - type request = t Jmap_standard_methods.Get.request 40 - type response = t Jmap_standard_methods.Get.response 39 + type request = t Standard_methods.Get.request 40 + type response = t Standard_methods.Get.response 41 41 42 42 val request_of_json : Ezjsonm.value -> request 43 43 val response_of_json : Ezjsonm.value -> response ··· 45 45 46 46 (** Standard /set method *) 47 47 module Set : sig 48 - type request = t Jmap_standard_methods.Set.request 49 - type response = t Jmap_standard_methods.Set.response 48 + type request = t Standard_methods.Set.request 49 + type response = t Standard_methods.Set.response 50 50 51 51 val request_of_json : Ezjsonm.value -> request 52 52 val response_of_json : Ezjsonm.value -> response
+34
stack/jmap/jmap.opam
··· 1 + # This file is generated by dune, edit dune-project instead 2 + opam-version: "2.0" 3 + version: "0.1.0" 4 + synopsis: "Unified JMAP library combining core, mail, and client" 5 + description: 6 + "Ergonomic, unified interface to the complete JMAP library (RFC 8620, RFC 8621). This is the recommended entry point for most users." 7 + maintainer: ["your.email@example.com"] 8 + authors: ["Your Name"] 9 + license: "MIT" 10 + homepage: "https://github.com/yourusername/jmap" 11 + bug-reports: "https://github.com/yourusername/jmap/issues" 12 + depends: [ 13 + "ocaml" {>= "4.14"} 14 + "dune" {>= "3.0" & >= "3.0"} 15 + "jmap-core" {= version} 16 + "jmap-mail" {= version} 17 + "jmap-client" {= version} 18 + "odoc" {with-doc} 19 + ] 20 + build: [ 21 + ["dune" "subst"] {dev} 22 + [ 23 + "dune" 24 + "build" 25 + "-p" 26 + name 27 + "-j" 28 + jobs 29 + "@install" 30 + "@runtest" {with-test} 31 + "@doc" {with-doc} 32 + ] 33 + ] 34 + dev-repo: "git+https://github.com/yourusername/jmap.git"
+5
stack/jmap/lib/dune
··· 1 + (library 2 + (name jmap) 3 + (public_name jmap) 4 + (libraries jmap-core jmap-mail jmap-client) 5 + (modules jmap))
+94
stack/jmap/lib/jmap.ml
··· 1 + (** Unified JMAP Library Interface 2 + 3 + This module provides a convenient, ergonomic interface to the complete JMAP library. 4 + It combines jmap-core, jmap-mail, and jmap-client into a single unified API. 5 + 6 + For most use cases, you should use this module. For specialized functionality, 7 + you can fall back to the individual submodules (Jmap_core, Jmap_mail, Jmap_client). 8 + *) 9 + 10 + (** {1 High-level Client API} *) 11 + 12 + (** JMAP HTTP Client - Start here for most use cases *) 13 + module Client = Jmap_client 14 + 15 + (** Connection configuration *) 16 + module Connection = Jmap_connection 17 + 18 + (** {1 Mail Extension (RFC 8621)} *) 19 + 20 + (** Email operations *) 21 + module Email = Jmap_mail.Email 22 + 23 + (** Mailbox operations *) 24 + module Mailbox = Jmap_mail.Mailbox 25 + 26 + (** Thread operations *) 27 + module Thread = Jmap_mail.Thread 28 + 29 + (** Identity management *) 30 + module Identity = Jmap_mail.Identity 31 + 32 + (** Email submission *) 33 + module Email_submission = Jmap_mail.Email_submission 34 + 35 + (** Vacation responses *) 36 + module Vacation_response = Jmap_mail.Vacation_response 37 + 38 + (** Search snippets *) 39 + module Search_snippet = Jmap_mail.Search_snippet 40 + 41 + (** Mail parsing utilities *) 42 + module Mail_parser = Jmap_mail.Mail_parser 43 + 44 + (** {1 Core Protocol (RFC 8620)} *) 45 + 46 + (** JMAP Session *) 47 + module Session = Jmap_core.Session 48 + 49 + (** Request building *) 50 + module Request = Jmap_core.Request 51 + 52 + (** Response handling *) 53 + module Response = Jmap_core.Response 54 + 55 + (** Method invocations *) 56 + module Invocation = Jmap_core.Invocation 57 + 58 + (** JMAP IDs *) 59 + module Id = Jmap_core.Id 60 + 61 + (** Capabilities *) 62 + module Capability = Jmap_core.Capability 63 + 64 + (** Filters *) 65 + module Filter = Jmap_core.Filter 66 + 67 + (** Comparators (sorting) *) 68 + module Comparator = Jmap_core.Comparator 69 + 70 + (** Primitive types *) 71 + module Primitives = Jmap_core.Primitives 72 + 73 + (** Standard methods *) 74 + module Standard_methods = Jmap_core.Standard_methods 75 + 76 + (** Error handling *) 77 + module Error = Jmap_core.Error 78 + 79 + (** Binary data (upload/download) *) 80 + module Binary = Jmap_core.Binary 81 + 82 + (** Push notifications *) 83 + module Push = Jmap_core.Push 84 + 85 + (** JSON parsing utilities *) 86 + module Parser = Jmap_core.Parser 87 + 88 + (** {1 Full Module Access} *) 89 + 90 + (** Complete jmap-core library *) 91 + module Core = Jmap_core 92 + 93 + (** Complete jmap-mail library *) 94 + module Mail = Jmap_mail
+125
stack/jmap/lib/jmap.mli
··· 1 + (** Unified JMAP Library Interface 2 + 3 + This module provides a convenient, ergonomic interface to the complete JMAP library. 4 + It combines jmap-core, jmap-mail, and jmap-client into a single unified API. 5 + 6 + For most use cases, you should use this module. For specialized functionality, 7 + you can fall back to the individual submodules (Jmap_core, Jmap_mail, Jmap_client). 8 + 9 + {2 Quick Start} 10 + 11 + {[ 12 + (* Create a client *) 13 + let client = Jmap.Client.create 14 + ~sw 15 + ~env 16 + ~conn:(Jmap.Connection.bearer_auth ~token:"your-token" ()) 17 + ~session_url:"https://api.example.com/.well-known/jmap" 18 + () 19 + 20 + (* Fetch session *) 21 + let session = Jmap.Client.get_session client 22 + 23 + (* Build and send a request *) 24 + let query_req = Jmap.Email.Query.request_v 25 + ~account_id:(Jmap.Id.of_string account_id) 26 + ~limit:(Jmap.Primitives.UnsignedInt.of_int 10) 27 + () 28 + in 29 + 30 + let query_args = Jmap.Email.Query.request_to_json query_req in 31 + let invocation = Jmap.Invocation.make_echo "Email/query" query_args "q1" in 32 + let req = Jmap.Request.make 33 + ~using:[Jmap.Capability.core; Jmap.Capability.mail] 34 + [invocation] 35 + in 36 + 37 + let resp = Jmap.Client.call client req 38 + ]} 39 + *) 40 + 41 + (** {1 High-level Client API} *) 42 + 43 + (** JMAP HTTP Client - Start here for most use cases *) 44 + module Client = Jmap_client 45 + 46 + (** Connection configuration *) 47 + module Connection = Jmap_connection 48 + 49 + (** {1 Mail Extension (RFC 8621)} *) 50 + 51 + (** Email operations *) 52 + module Email = Jmap_mail.Email 53 + 54 + (** Mailbox operations *) 55 + module Mailbox = Jmap_mail.Mailbox 56 + 57 + (** Thread operations *) 58 + module Thread = Jmap_mail.Thread 59 + 60 + (** Identity management *) 61 + module Identity = Jmap_mail.Identity 62 + 63 + (** Email submission *) 64 + module Email_submission = Jmap_mail.Email_submission 65 + 66 + (** Vacation responses *) 67 + module Vacation_response = Jmap_mail.Vacation_response 68 + 69 + (** Search snippets *) 70 + module Search_snippet = Jmap_mail.Search_snippet 71 + 72 + (** Mail parsing utilities *) 73 + module Mail_parser = Jmap_mail.Mail_parser 74 + 75 + (** {1 Core Protocol (RFC 8620)} *) 76 + 77 + (** JMAP Session *) 78 + module Session = Jmap_core.Session 79 + 80 + (** Request building *) 81 + module Request = Jmap_core.Request 82 + 83 + (** Response handling *) 84 + module Response = Jmap_core.Response 85 + 86 + (** Method invocations *) 87 + module Invocation = Jmap_core.Invocation 88 + 89 + (** JMAP IDs *) 90 + module Id = Jmap_core.Id 91 + 92 + (** Capabilities *) 93 + module Capability = Jmap_core.Capability 94 + 95 + (** Filters *) 96 + module Filter = Jmap_core.Filter 97 + 98 + (** Comparators (sorting) *) 99 + module Comparator = Jmap_core.Comparator 100 + 101 + (** Primitive types *) 102 + module Primitives = Jmap_core.Primitives 103 + 104 + (** Standard methods *) 105 + module Standard_methods = Jmap_core.Standard_methods 106 + 107 + (** Error handling *) 108 + module Error = Jmap_core.Error 109 + 110 + (** Binary data (upload/download) *) 111 + module Binary = Jmap_core.Binary 112 + 113 + (** Push notifications *) 114 + module Push = Jmap_core.Push 115 + 116 + (** JSON parsing utilities *) 117 + module Parser = Jmap_core.Parser 118 + 119 + (** {1 Full Module Access} *) 120 + 121 + (** Complete jmap-core library *) 122 + module Core = Jmap_core 123 + 124 + (** Complete jmap-mail library *) 125 + module Mail = Jmap_mail
+5
stack/jmap/test/dune
··· 14 14 (name test_simple_https) 15 15 (libraries eio_main requests mirage-crypto-rng.unix) 16 16 (modes exe)) 17 + 18 + (executable 19 + (name test_unified_api) 20 + (libraries jmap jmap-core jmap-mail) 21 + (modes exe))
+28 -28
stack/jmap/test/test_fastmail.ml
··· 55 55 Printf.printf "Fetching JMAP session...\n%!"; 56 56 let session = Jmap_client.fetch_session client in 57 57 Printf.printf "✓ Session fetched\n"; 58 - Printf.printf " Username: %s\n" (Jmap_core.Jmap_session.username session); 59 - Printf.printf " API URL: %s\n\n%!" (Jmap_core.Jmap_session.api_url session); 58 + Printf.printf " Username: %s\n" (Jmap_core.Session.username session); 59 + Printf.printf " API URL: %s\n\n%!" (Jmap_core.Session.api_url session); 60 60 61 61 (* Get primary mail account *) 62 - let primary_accounts = Jmap_core.Jmap_session.primary_accounts session in 62 + let primary_accounts = Jmap_core.Session.primary_accounts session in 63 63 let account_id = match List.assoc_opt "urn:ietf:params:jmap:mail" primary_accounts with 64 - | Some id -> Jmap_core.Jmap_id.to_string id 64 + | Some id -> Jmap_core.Id.to_string id 65 65 | None -> 66 66 Printf.eprintf "Error: No mail account found\n"; 67 67 exit 1 ··· 70 70 71 71 (* Build a JMAP request using the typed library API *) 72 72 Printf.printf "Querying for 10 most recent emails...\n"; 73 - Printf.printf " API URL: %s\n%!" (Jmap_core.Jmap_session.api_url session); 73 + Printf.printf " API URL: %s\n%!" (Jmap_core.Session.api_url session); 74 74 75 75 (* Build Email/query request using typed constructors *) 76 - let query_request = Jmap_mail.Jmap_email.Query.request_v 77 - ~account_id:(Jmap_core.Jmap_id.of_string account_id) 78 - ~limit:(Jmap_core.Jmap_primitives.UnsignedInt.of_int 10) 79 - ~sort:[Jmap_core.Jmap_comparator.v ~property:"receivedAt" ~is_ascending:false ()] 76 + let query_request = Jmap_mail.Email.Query.request_v 77 + ~account_id:(Jmap_core.Id.of_string account_id) 78 + ~limit:(Jmap_core.Primitives.UnsignedInt.of_int 10) 79 + ~sort:[Jmap_core.Comparator.v ~property:"receivedAt" ~is_ascending:false ()] 80 80 ~calculate_total:true 81 81 () in 82 82 83 83 (* Convert to JSON *) 84 - let query_args = Jmap_mail.Jmap_email.Query.request_to_json query_request in 84 + let query_args = Jmap_mail.Email.Query.request_to_json query_request in 85 85 86 86 (* Create invocation using Echo witness *) 87 - let query_invocation = Jmap_core.Jmap_invocation.Invocation { 87 + let query_invocation = Jmap_core.Invocation.Invocation { 88 88 method_name = "Email/query"; 89 89 arguments = query_args; 90 90 call_id = "q1"; 91 - witness = Jmap_core.Jmap_invocation.Echo; 91 + witness = Jmap_core.Invocation.Echo; 92 92 } in 93 93 94 94 (* Build request using constructors *) 95 - let req = Jmap_core.Jmap_request.make 96 - ~using:[Jmap_core.Jmap_capability.core; Jmap_core.Jmap_capability.mail] 97 - [Jmap_core.Jmap_invocation.Packed query_invocation] 95 + let req = Jmap_core.Request.make 96 + ~using:[Jmap_core.Capability.core; Jmap_core.Capability.mail] 97 + [Jmap_core.Invocation.Packed query_invocation] 98 98 in 99 99 100 100 Printf.printf " Request built using typed Email.Query API\n%!"; ··· 105 105 Printf.printf "✓ Query successful!\n"; 106 106 107 107 (* Extract email IDs from the query response *) 108 - let method_responses = Jmap_core.Jmap_response.method_responses query_resp in 108 + let method_responses = Jmap_core.Response.method_responses query_resp in 109 109 let email_ids = match method_responses with 110 110 | [packed_resp] -> 111 - let response_json = Jmap_core.Jmap_invocation.response_to_json packed_resp in 111 + let response_json = Jmap_core.Invocation.response_to_json packed_resp in 112 112 (match response_json with 113 113 | `O fields -> 114 114 (match List.assoc_opt "ids" fields with 115 115 | Some (`A ids) -> 116 116 List.map (fun id -> 117 117 match id with 118 - | `String s -> Jmap_core.Jmap_id.of_string s 118 + | `String s -> Jmap_core.Id.of_string s 119 119 | _ -> failwith "Expected string ID" 120 120 ) ids 121 121 | _ -> failwith "No 'ids' field in query response") ··· 127 127 128 128 if List.length email_ids > 0 then ( 129 129 (* Fetch the actual emails with Email/get *) 130 - let get_request = Jmap_mail.Jmap_email.Get.request_v 131 - ~account_id:(Jmap_core.Jmap_id.of_string account_id) 130 + let get_request = Jmap_mail.Email.Get.request_v 131 + ~account_id:(Jmap_core.Id.of_string account_id) 132 132 ~ids:email_ids 133 133 ~properties:["id"; "subject"; "from"; "receivedAt"] 134 134 () in 135 135 136 - let get_args = Jmap_mail.Jmap_email.Get.request_to_json get_request in 136 + let get_args = Jmap_mail.Email.Get.request_to_json get_request in 137 137 138 - let get_invocation = Jmap_core.Jmap_invocation.Invocation { 138 + let get_invocation = Jmap_core.Invocation.Invocation { 139 139 method_name = "Email/get"; 140 140 arguments = get_args; 141 141 call_id = "g1"; 142 - witness = Jmap_core.Jmap_invocation.Echo; 142 + witness = Jmap_core.Invocation.Echo; 143 143 } in 144 144 145 - let get_req = Jmap_core.Jmap_request.make 146 - ~using:[Jmap_core.Jmap_capability.core; Jmap_core.Jmap_capability.mail] 147 - [Jmap_core.Jmap_invocation.Packed get_invocation] 145 + let get_req = Jmap_core.Request.make 146 + ~using:[Jmap_core.Capability.core; Jmap_core.Capability.mail] 147 + [Jmap_core.Invocation.Packed get_invocation] 148 148 in 149 149 150 150 let get_resp = Jmap_client.call client get_req in 151 151 152 152 (* Parse and display emails *) 153 - let get_method_responses = Jmap_core.Jmap_response.method_responses get_resp in 153 + let get_method_responses = Jmap_core.Response.method_responses get_resp in 154 154 (match get_method_responses with 155 155 | [packed_resp] -> 156 - let response_json = Jmap_core.Jmap_invocation.response_to_json packed_resp in 156 + let response_json = Jmap_core.Invocation.response_to_json packed_resp in 157 157 (match response_json with 158 158 | `O fields -> 159 159 (match List.assoc_opt "list" fields with
+264 -264
stack/jmap/test/test_jmap.ml
··· 57 57 58 58 let test_mailbox_get_request () = 59 59 let json = load_json "data/mail/mailbox_get_request.json" in 60 - let req = Jmap_mail.Jmap_mailbox.Get.request_of_json json in 60 + let req = Jmap_mail.Mailbox.Get.request_of_json json in 61 61 62 62 (* Verify account_id *) 63 - let account_id = Jmap_core.Jmap_standard_methods.Get.account_id req in 64 - check string "Account ID" "u123456" (Jmap_core.Jmap_id.to_string account_id); 63 + let account_id = Jmap_core.Standard_methods.Get.account_id req in 64 + check string "Account ID" "u123456" (Jmap_core.Id.to_string account_id); 65 65 66 66 (* Verify ids is null (None) *) 67 - let ids = Jmap_core.Jmap_standard_methods.Get.ids req in 67 + let ids = Jmap_core.Standard_methods.Get.ids req in 68 68 check bool "IDs should be None" true (ids = None); 69 69 70 70 (* Verify properties list *) 71 - let props = Jmap_core.Jmap_standard_methods.Get.properties req in 71 + let props = Jmap_core.Standard_methods.Get.properties req in 72 72 match props with 73 73 | Some p -> 74 74 check int "Properties count" 11 (List.length p); ··· 81 81 82 82 let test_mailbox_get_response () = 83 83 let json = load_json "data/mail/mailbox_get_response.json" in 84 - let resp = Jmap_mail.Jmap_mailbox.Get.response_of_json json in 84 + let resp = Jmap_mail.Mailbox.Get.response_of_json json in 85 85 86 86 (* Verify account_id *) 87 - let account_id = Jmap_core.Jmap_standard_methods.Get.response_account_id resp in 88 - check string "Account ID" "u123456" (Jmap_core.Jmap_id.to_string account_id); 87 + let account_id = Jmap_core.Standard_methods.Get.response_account_id resp in 88 + check string "Account ID" "u123456" (Jmap_core.Id.to_string account_id); 89 89 90 90 (* Verify state *) 91 - let state = Jmap_core.Jmap_standard_methods.Get.state resp in 91 + let state = Jmap_core.Standard_methods.Get.state resp in 92 92 check string "State" "m42:100" state; 93 93 94 94 (* Verify mailbox list *) 95 - let mailboxes = Jmap_core.Jmap_standard_methods.Get.list resp in 95 + let mailboxes = Jmap_core.Standard_methods.Get.list resp in 96 96 check int "Mailbox count" 5 (List.length mailboxes); 97 97 98 98 (* Verify not_found is empty *) 99 - let not_found = Jmap_core.Jmap_standard_methods.Get.not_found resp in 99 + let not_found = Jmap_core.Standard_methods.Get.not_found resp in 100 100 check int "Not found count" 0 (List.length not_found); 101 101 102 102 (* Test first mailbox (INBOX) *) 103 103 let inbox = List.hd mailboxes in 104 - check string "INBOX id" "mb001" (Jmap_core.Jmap_id.to_string (Jmap_mail.Jmap_mailbox.id inbox)); 105 - check string "INBOX name" "INBOX" (Jmap_mail.Jmap_mailbox.name inbox); 106 - check bool "INBOX parentId is None" true (Jmap_mail.Jmap_mailbox.parent_id inbox = None); 107 - check string "INBOX role" "inbox" (match Jmap_mail.Jmap_mailbox.role inbox with Some r -> r | None -> ""); 108 - check int "INBOX sortOrder" 10 (Jmap_core.Jmap_primitives.UnsignedInt.to_int (Jmap_mail.Jmap_mailbox.sort_order inbox)); 109 - check int "INBOX totalEmails" 1523 (Jmap_core.Jmap_primitives.UnsignedInt.to_int (Jmap_mail.Jmap_mailbox.total_emails inbox)); 110 - check int "INBOX unreadEmails" 42 (Jmap_core.Jmap_primitives.UnsignedInt.to_int (Jmap_mail.Jmap_mailbox.unread_emails inbox)); 111 - check int "INBOX totalThreads" 987 (Jmap_core.Jmap_primitives.UnsignedInt.to_int (Jmap_mail.Jmap_mailbox.total_threads inbox)); 112 - check int "INBOX unreadThreads" 35 (Jmap_core.Jmap_primitives.UnsignedInt.to_int (Jmap_mail.Jmap_mailbox.unread_threads inbox)); 113 - check bool "INBOX isSubscribed" true (Jmap_mail.Jmap_mailbox.is_subscribed inbox); 104 + check string "INBOX id" "mb001" (Jmap_core.Id.to_string (Jmap_mail.Mailbox.id inbox)); 105 + check string "INBOX name" "INBOX" (Jmap_mail.Mailbox.name inbox); 106 + check bool "INBOX parentId is None" true (Jmap_mail.Mailbox.parent_id inbox = None); 107 + check string "INBOX role" "inbox" (match Jmap_mail.Mailbox.role inbox with Some r -> r | None -> ""); 108 + check int "INBOX sortOrder" 10 (Jmap_core.Primitives.UnsignedInt.to_int (Jmap_mail.Mailbox.sort_order inbox)); 109 + check int "INBOX totalEmails" 1523 (Jmap_core.Primitives.UnsignedInt.to_int (Jmap_mail.Mailbox.total_emails inbox)); 110 + check int "INBOX unreadEmails" 42 (Jmap_core.Primitives.UnsignedInt.to_int (Jmap_mail.Mailbox.unread_emails inbox)); 111 + check int "INBOX totalThreads" 987 (Jmap_core.Primitives.UnsignedInt.to_int (Jmap_mail.Mailbox.total_threads inbox)); 112 + check int "INBOX unreadThreads" 35 (Jmap_core.Primitives.UnsignedInt.to_int (Jmap_mail.Mailbox.unread_threads inbox)); 113 + check bool "INBOX isSubscribed" true (Jmap_mail.Mailbox.is_subscribed inbox); 114 114 115 115 (* Test INBOX rights *) 116 - let inbox_rights = Jmap_mail.Jmap_mailbox.my_rights inbox in 117 - check bool "INBOX mayReadItems" true (Jmap_mail.Jmap_mailbox.Rights.may_read_items inbox_rights); 118 - check bool "INBOX mayAddItems" true (Jmap_mail.Jmap_mailbox.Rights.may_add_items inbox_rights); 119 - check bool "INBOX mayRemoveItems" true (Jmap_mail.Jmap_mailbox.Rights.may_remove_items inbox_rights); 120 - check bool "INBOX maySetSeen" true (Jmap_mail.Jmap_mailbox.Rights.may_set_seen inbox_rights); 121 - check bool "INBOX maySetKeywords" true (Jmap_mail.Jmap_mailbox.Rights.may_set_keywords inbox_rights); 122 - check bool "INBOX mayCreateChild" true (Jmap_mail.Jmap_mailbox.Rights.may_create_child inbox_rights); 123 - check bool "INBOX mayRename" false (Jmap_mail.Jmap_mailbox.Rights.may_rename inbox_rights); 124 - check bool "INBOX mayDelete" false (Jmap_mail.Jmap_mailbox.Rights.may_delete inbox_rights); 125 - check bool "INBOX maySubmit" true (Jmap_mail.Jmap_mailbox.Rights.may_submit inbox_rights); 116 + let inbox_rights = Jmap_mail.Mailbox.my_rights inbox in 117 + check bool "INBOX mayReadItems" true (Jmap_mail.Mailbox.Rights.may_read_items inbox_rights); 118 + check bool "INBOX mayAddItems" true (Jmap_mail.Mailbox.Rights.may_add_items inbox_rights); 119 + check bool "INBOX mayRemoveItems" true (Jmap_mail.Mailbox.Rights.may_remove_items inbox_rights); 120 + check bool "INBOX maySetSeen" true (Jmap_mail.Mailbox.Rights.may_set_seen inbox_rights); 121 + check bool "INBOX maySetKeywords" true (Jmap_mail.Mailbox.Rights.may_set_keywords inbox_rights); 122 + check bool "INBOX mayCreateChild" true (Jmap_mail.Mailbox.Rights.may_create_child inbox_rights); 123 + check bool "INBOX mayRename" false (Jmap_mail.Mailbox.Rights.may_rename inbox_rights); 124 + check bool "INBOX mayDelete" false (Jmap_mail.Mailbox.Rights.may_delete inbox_rights); 125 + check bool "INBOX maySubmit" true (Jmap_mail.Mailbox.Rights.may_submit inbox_rights); 126 126 127 127 (* Test second mailbox (Sent) *) 128 128 let sent = List.nth mailboxes 1 in 129 - check string "Sent id" "mb002" (Jmap_core.Jmap_id.to_string (Jmap_mail.Jmap_mailbox.id sent)); 130 - check string "Sent name" "Sent" (Jmap_mail.Jmap_mailbox.name sent); 131 - check string "Sent role" "sent" (match Jmap_mail.Jmap_mailbox.role sent with Some r -> r | None -> ""); 132 - check int "Sent sortOrder" 20 (Jmap_core.Jmap_primitives.UnsignedInt.to_int (Jmap_mail.Jmap_mailbox.sort_order sent)); 129 + check string "Sent id" "mb002" (Jmap_core.Id.to_string (Jmap_mail.Mailbox.id sent)); 130 + check string "Sent name" "Sent" (Jmap_mail.Mailbox.name sent); 131 + check string "Sent role" "sent" (match Jmap_mail.Mailbox.role sent with Some r -> r | None -> ""); 132 + check int "Sent sortOrder" 20 (Jmap_core.Primitives.UnsignedInt.to_int (Jmap_mail.Mailbox.sort_order sent)); 133 133 134 134 (* Test Work mailbox (no role) *) 135 135 let work = List.nth mailboxes 4 in 136 - check string "Work id" "mb005" (Jmap_core.Jmap_id.to_string (Jmap_mail.Jmap_mailbox.id work)); 137 - check string "Work name" "Work" (Jmap_mail.Jmap_mailbox.name work); 138 - check bool "Work role is None" true (Jmap_mail.Jmap_mailbox.role work = None); 139 - check int "Work totalEmails" 342 (Jmap_core.Jmap_primitives.UnsignedInt.to_int (Jmap_mail.Jmap_mailbox.total_emails work)); 136 + check string "Work id" "mb005" (Jmap_core.Id.to_string (Jmap_mail.Mailbox.id work)); 137 + check string "Work name" "Work" (Jmap_mail.Mailbox.name work); 138 + check bool "Work role is None" true (Jmap_mail.Mailbox.role work = None); 139 + check int "Work totalEmails" 342 (Jmap_core.Primitives.UnsignedInt.to_int (Jmap_mail.Mailbox.total_emails work)); 140 140 141 141 (* Test Work rights (user-created mailbox has full permissions) *) 142 - let work_rights = Jmap_mail.Jmap_mailbox.my_rights work in 143 - check bool "Work mayRename" true (Jmap_mail.Jmap_mailbox.Rights.may_rename work_rights); 144 - check bool "Work mayDelete" true (Jmap_mail.Jmap_mailbox.Rights.may_delete work_rights) 142 + let work_rights = Jmap_mail.Mailbox.my_rights work in 143 + check bool "Work mayRename" true (Jmap_mail.Mailbox.Rights.may_rename work_rights); 144 + check bool "Work mayDelete" true (Jmap_mail.Mailbox.Rights.may_delete work_rights) 145 145 146 146 let test_mailbox_query_request () = 147 147 let json = load_json "data/mail/mailbox_query_request.json" in 148 - let req = Jmap_mail.Jmap_mailbox.Query.request_of_json json in 148 + let req = Jmap_mail.Mailbox.Query.request_of_json json in 149 149 150 150 (* Verify account_id *) 151 - let account_id = Jmap_mail.Jmap_mailbox.Query.account_id req in 152 - check string "Account ID" "u123456" (Jmap_core.Jmap_id.to_string account_id); 151 + let account_id = Jmap_mail.Mailbox.Query.account_id req in 152 + check string "Account ID" "u123456" (Jmap_core.Id.to_string account_id); 153 153 154 154 (* Verify filter is present *) 155 - let filter = Jmap_mail.Jmap_mailbox.Query.filter req in 155 + let filter = Jmap_mail.Mailbox.Query.filter req in 156 156 check bool "Filter should be Some" true (filter <> None); 157 157 158 158 (* Verify sort *) 159 - let sort = Jmap_mail.Jmap_mailbox.Query.sort req in 159 + let sort = Jmap_mail.Mailbox.Query.sort req in 160 160 match sort with 161 161 | Some s -> 162 162 check int "Sort criteria count" 2 (List.length s); 163 163 (* First sort by sortOrder ascending *) 164 164 let sort1 = List.hd s in 165 - check string "First sort property" "sortOrder" (Jmap_core.Jmap_comparator.property sort1); 166 - check bool "First sort ascending" true (Jmap_core.Jmap_comparator.is_ascending sort1); 165 + check string "First sort property" "sortOrder" (Jmap_core.Comparator.property sort1); 166 + check bool "First sort ascending" true (Jmap_core.Comparator.is_ascending sort1); 167 167 (* Second sort by name ascending *) 168 168 let sort2 = List.nth s 1 in 169 - check string "Second sort property" "name" (Jmap_core.Jmap_comparator.property sort2); 170 - check bool "Second sort ascending" true (Jmap_core.Jmap_comparator.is_ascending sort2) 169 + check string "Second sort property" "name" (Jmap_core.Comparator.property sort2); 170 + check bool "Second sort ascending" true (Jmap_core.Comparator.is_ascending sort2) 171 171 | None -> 172 172 fail "Sort should not be None"; 173 173 174 174 (* Verify calculateTotal *) 175 - let calculate_total = Jmap_mail.Jmap_mailbox.Query.calculate_total req in 175 + let calculate_total = Jmap_mail.Mailbox.Query.calculate_total req in 176 176 check bool "Calculate total should be Some true" true (calculate_total = Some true) 177 177 178 178 let test_mailbox_query_response () = 179 179 let json = load_json "data/mail/mailbox_query_response.json" in 180 - let resp = Jmap_mail.Jmap_mailbox.Query.response_of_json json in 180 + let resp = Jmap_mail.Mailbox.Query.response_of_json json in 181 181 182 182 (* Verify account_id *) 183 - let account_id = Jmap_core.Jmap_standard_methods.Query.response_account_id resp in 184 - check string "Account ID" "u123456" (Jmap_core.Jmap_id.to_string account_id); 183 + let account_id = Jmap_core.Standard_methods.Query.response_account_id resp in 184 + check string "Account ID" "u123456" (Jmap_core.Id.to_string account_id); 185 185 186 186 (* Verify query_state *) 187 - let query_state = Jmap_core.Jmap_standard_methods.Query.query_state resp in 187 + let query_state = Jmap_core.Standard_methods.Query.query_state resp in 188 188 check string "Query state" "mq42:100" query_state; 189 189 190 190 (* Verify can_calculate_changes *) 191 - let can_calc = Jmap_core.Jmap_standard_methods.Query.can_calculate_changes resp in 191 + let can_calc = Jmap_core.Standard_methods.Query.can_calculate_changes resp in 192 192 check bool "Can calculate changes" true can_calc; 193 193 194 194 (* Verify position *) 195 - let position = Jmap_core.Jmap_standard_methods.Query.response_position resp in 196 - check int "Position" 0 (Jmap_core.Jmap_primitives.UnsignedInt.to_int position); 195 + let position = Jmap_core.Standard_methods.Query.response_position resp in 196 + check int "Position" 0 (Jmap_core.Primitives.UnsignedInt.to_int position); 197 197 198 198 (* Verify ids *) 199 - let ids = Jmap_core.Jmap_standard_methods.Query.ids resp in 199 + let ids = Jmap_core.Standard_methods.Query.ids resp in 200 200 check int "IDs count" 3 (List.length ids); 201 - check string "First ID" "mb005" (Jmap_core.Jmap_id.to_string (List.hd ids)); 202 - check string "Second ID" "mb008" (Jmap_core.Jmap_id.to_string (List.nth ids 1)); 203 - check string "Third ID" "mb012" (Jmap_core.Jmap_id.to_string (List.nth ids 2)); 201 + check string "First ID" "mb005" (Jmap_core.Id.to_string (List.hd ids)); 202 + check string "Second ID" "mb008" (Jmap_core.Id.to_string (List.nth ids 1)); 203 + check string "Third ID" "mb012" (Jmap_core.Id.to_string (List.nth ids 2)); 204 204 205 205 (* Verify total *) 206 - let total = Jmap_core.Jmap_standard_methods.Query.total resp in 206 + let total = Jmap_core.Standard_methods.Query.total resp in 207 207 match total with 208 - | Some t -> check int "Total" 3 (Jmap_core.Jmap_primitives.UnsignedInt.to_int t) 208 + | Some t -> check int "Total" 3 (Jmap_core.Primitives.UnsignedInt.to_int t) 209 209 | None -> fail "Total should not be None" 210 210 211 211 let test_mailbox_set_request () = 212 212 let json = load_json "data/mail/mailbox_set_request.json" in 213 - let req = Jmap_mail.Jmap_mailbox.Set.request_of_json json in 213 + let req = Jmap_mail.Mailbox.Set.request_of_json json in 214 214 215 215 (* Verify account_id *) 216 - let account_id = Jmap_core.Jmap_standard_methods.Set.account_id req in 217 - check string "Account ID" "u123456" (Jmap_core.Jmap_id.to_string account_id); 216 + let account_id = Jmap_core.Standard_methods.Set.account_id req in 217 + check string "Account ID" "u123456" (Jmap_core.Id.to_string account_id); 218 218 219 219 (* Verify if_in_state *) 220 - let if_in_state = Jmap_core.Jmap_standard_methods.Set.if_in_state req in 220 + let if_in_state = Jmap_core.Standard_methods.Set.if_in_state req in 221 221 check bool "If in state should be Some" true (if_in_state = Some "m42:100"); 222 222 223 223 (* Verify create *) 224 - let create = Jmap_core.Jmap_standard_methods.Set.create req in 224 + let create = Jmap_core.Standard_methods.Set.create req in 225 225 (match create with 226 226 | Some c -> 227 227 check int "Create count" 1 (List.length c); 228 228 let (temp_id, mailbox) = List.hd c in 229 - check string "Temp ID" "temp-mb-1" (Jmap_core.Jmap_id.to_string temp_id); 230 - check string "Created mailbox name" "Projects" (Jmap_mail.Jmap_mailbox.name mailbox); 231 - check bool "Created mailbox parentId is None" true (Jmap_mail.Jmap_mailbox.parent_id mailbox = None); 232 - check bool "Created mailbox role is None" true (Jmap_mail.Jmap_mailbox.role mailbox = None); 233 - check int "Created mailbox sortOrder" 60 (Jmap_core.Jmap_primitives.UnsignedInt.to_int (Jmap_mail.Jmap_mailbox.sort_order mailbox)); 234 - check bool "Created mailbox isSubscribed" true (Jmap_mail.Jmap_mailbox.is_subscribed mailbox) 229 + check string "Temp ID" "temp-mb-1" (Jmap_core.Id.to_string temp_id); 230 + check string "Created mailbox name" "Projects" (Jmap_mail.Mailbox.name mailbox); 231 + check bool "Created mailbox parentId is None" true (Jmap_mail.Mailbox.parent_id mailbox = None); 232 + check bool "Created mailbox role is None" true (Jmap_mail.Mailbox.role mailbox = None); 233 + check int "Created mailbox sortOrder" 60 (Jmap_core.Primitives.UnsignedInt.to_int (Jmap_mail.Mailbox.sort_order mailbox)); 234 + check bool "Created mailbox isSubscribed" true (Jmap_mail.Mailbox.is_subscribed mailbox) 235 235 | None -> 236 236 fail "Create should not be None"); 237 237 238 238 (* Verify update *) 239 - let update = Jmap_core.Jmap_standard_methods.Set.update req in 239 + let update = Jmap_core.Standard_methods.Set.update req in 240 240 (match update with 241 241 | Some u -> 242 242 check int "Update count" 1 (List.length u); 243 243 let (update_id, _patches) = List.hd u in 244 - check string "Update ID" "mb005" (Jmap_core.Jmap_id.to_string update_id) 244 + check string "Update ID" "mb005" (Jmap_core.Id.to_string update_id) 245 245 | None -> 246 246 fail "Update should not be None"); 247 247 248 248 (* Verify destroy *) 249 - let destroy = Jmap_core.Jmap_standard_methods.Set.destroy req in 249 + let destroy = Jmap_core.Standard_methods.Set.destroy req in 250 250 (match destroy with 251 251 | Some d -> 252 252 check int "Destroy count" 1 (List.length d); 253 - check string "Destroy ID" "mb012" (Jmap_core.Jmap_id.to_string (List.hd d)) 253 + check string "Destroy ID" "mb012" (Jmap_core.Id.to_string (List.hd d)) 254 254 | None -> 255 255 fail "Destroy should not be None") 256 256 257 257 let test_mailbox_set_response () = 258 258 let json = load_json "data/mail/mailbox_set_response.json" in 259 - let resp = Jmap_mail.Jmap_mailbox.Set.response_of_json json in 259 + let resp = Jmap_mail.Mailbox.Set.response_of_json json in 260 260 261 261 (* Verify account_id *) 262 - let account_id = Jmap_core.Jmap_standard_methods.Set.response_account_id resp in 263 - check string "Account ID" "u123456" (Jmap_core.Jmap_id.to_string account_id); 262 + let account_id = Jmap_core.Standard_methods.Set.response_account_id resp in 263 + check string "Account ID" "u123456" (Jmap_core.Id.to_string account_id); 264 264 265 265 (* Verify old_state *) 266 - let old_state = Jmap_core.Jmap_standard_methods.Set.old_state resp in 266 + let old_state = Jmap_core.Standard_methods.Set.old_state resp in 267 267 check bool "Old state should be Some" true (old_state = Some "m42:100"); 268 268 269 269 (* Verify new_state *) 270 - let new_state = Jmap_core.Jmap_standard_methods.Set.new_state resp in 270 + let new_state = Jmap_core.Standard_methods.Set.new_state resp in 271 271 check string "New state" "m42:103" new_state; 272 272 273 273 (* Verify created *) 274 - let created = Jmap_core.Jmap_standard_methods.Set.created resp in 274 + let created = Jmap_core.Standard_methods.Set.created resp in 275 275 (match created with 276 276 | Some c -> 277 277 check int "Created count" 1 (List.length c); 278 278 let (temp_id, mailbox) = List.hd c in 279 - check string "Created temp ID" "temp-mb-1" (Jmap_core.Jmap_id.to_string temp_id); 280 - check string "Created mailbox ID" "mb020" (Jmap_core.Jmap_id.to_string (Jmap_mail.Jmap_mailbox.id mailbox)); 281 - check int "Created mailbox totalEmails" 0 (Jmap_core.Jmap_primitives.UnsignedInt.to_int (Jmap_mail.Jmap_mailbox.total_emails mailbox)); 282 - check int "Created mailbox unreadEmails" 0 (Jmap_core.Jmap_primitives.UnsignedInt.to_int (Jmap_mail.Jmap_mailbox.unread_emails mailbox)); 279 + check string "Created temp ID" "temp-mb-1" (Jmap_core.Id.to_string temp_id); 280 + check string "Created mailbox ID" "mb020" (Jmap_core.Id.to_string (Jmap_mail.Mailbox.id mailbox)); 281 + check int "Created mailbox totalEmails" 0 (Jmap_core.Primitives.UnsignedInt.to_int (Jmap_mail.Mailbox.total_emails mailbox)); 282 + check int "Created mailbox unreadEmails" 0 (Jmap_core.Primitives.UnsignedInt.to_int (Jmap_mail.Mailbox.unread_emails mailbox)); 283 283 (* Verify rights of created mailbox *) 284 - let rights = Jmap_mail.Jmap_mailbox.my_rights mailbox in 285 - check bool "Created mailbox mayRename" true (Jmap_mail.Jmap_mailbox.Rights.may_rename rights); 286 - check bool "Created mailbox mayDelete" true (Jmap_mail.Jmap_mailbox.Rights.may_delete rights) 284 + let rights = Jmap_mail.Mailbox.my_rights mailbox in 285 + check bool "Created mailbox mayRename" true (Jmap_mail.Mailbox.Rights.may_rename rights); 286 + check bool "Created mailbox mayDelete" true (Jmap_mail.Mailbox.Rights.may_delete rights) 287 287 | None -> 288 288 fail "Created should not be None"); 289 289 290 290 (* Verify updated *) 291 - let updated = Jmap_core.Jmap_standard_methods.Set.updated resp in 291 + let updated = Jmap_core.Standard_methods.Set.updated resp in 292 292 (match updated with 293 293 | Some u -> 294 294 check int "Updated count" 1 (List.length u); 295 295 let (update_id, update_val) = List.hd u in 296 - check string "Updated ID" "mb005" (Jmap_core.Jmap_id.to_string update_id); 296 + check string "Updated ID" "mb005" (Jmap_core.Id.to_string update_id); 297 297 check bool "Updated value is None" true (update_val = None) 298 298 | None -> 299 299 fail "Updated should not be None"); 300 300 301 301 (* Verify destroyed *) 302 - let destroyed = Jmap_core.Jmap_standard_methods.Set.destroyed resp in 302 + let destroyed = Jmap_core.Standard_methods.Set.destroyed resp in 303 303 (match destroyed with 304 304 | Some d -> 305 305 check int "Destroyed count" 1 (List.length d); 306 - check string "Destroyed ID" "mb012" (Jmap_core.Jmap_id.to_string (List.hd d)) 306 + check string "Destroyed ID" "mb012" (Jmap_core.Id.to_string (List.hd d)) 307 307 | None -> 308 308 fail "Destroyed should not be None"); 309 309 310 310 (* Verify not_created, not_updated, not_destroyed are None *) 311 - check bool "Not created is None" true (Jmap_core.Jmap_standard_methods.Set.not_created resp = None); 312 - check bool "Not updated is None" true (Jmap_core.Jmap_standard_methods.Set.not_updated resp = None); 313 - check bool "Not destroyed is None" true (Jmap_core.Jmap_standard_methods.Set.not_destroyed resp = None) 311 + check bool "Not created is None" true (Jmap_core.Standard_methods.Set.not_created resp = None); 312 + check bool "Not updated is None" true (Jmap_core.Standard_methods.Set.not_updated resp = None); 313 + check bool "Not destroyed is None" true (Jmap_core.Standard_methods.Set.not_destroyed resp = None) 314 314 315 315 (** Test Mail Protocol - Email *) 316 316 317 317 let test_email_get_request () = 318 318 let json = load_json "data/mail/email_get_request.json" in 319 - let request = Jmap_mail.Jmap_email.Get.request_of_json json in 319 + let request = Jmap_mail.Email.Get.request_of_json json in 320 320 321 321 (* Validate account_id *) 322 - let account_id = Jmap_mail.Jmap_email.Get.account_id request in 323 - check string "Account ID" "u123456" (Jmap_core.Jmap_id.to_string account_id); 322 + let account_id = Jmap_mail.Email.Get.account_id request in 323 + check string "Account ID" "u123456" (Jmap_core.Id.to_string account_id); 324 324 325 325 (* Validate ids *) 326 - let ids = Jmap_mail.Jmap_email.Get.ids request in 326 + let ids = Jmap_mail.Email.Get.ids request in 327 327 check bool "IDs present" true (Option.is_some ids); 328 328 let ids_list = Option.get ids in 329 329 check int "Two IDs requested" 2 (List.length ids_list); 330 - check string "First ID" "e001" (Jmap_core.Jmap_id.to_string (List.nth ids_list 0)); 331 - check string "Second ID" "e002" (Jmap_core.Jmap_id.to_string (List.nth ids_list 1)); 330 + check string "First ID" "e001" (Jmap_core.Id.to_string (List.nth ids_list 0)); 331 + check string "Second ID" "e002" (Jmap_core.Id.to_string (List.nth ids_list 1)); 332 332 333 333 (* Validate properties *) 334 - let properties = Jmap_mail.Jmap_email.Get.properties request in 334 + let properties = Jmap_mail.Email.Get.properties request in 335 335 check bool "Properties present" true (Option.is_some properties); 336 336 let props_list = Option.get properties in 337 337 check bool "Properties include 'subject'" true (List.mem "subject" props_list); ··· 340 340 341 341 let test_email_get_full_request () = 342 342 let json = load_json "data/mail/email_get_full_request.json" in 343 - let request = Jmap_mail.Jmap_email.Get.request_of_json json in 343 + let request = Jmap_mail.Email.Get.request_of_json json in 344 344 345 345 (* Validate body fetch options *) 346 - let fetch_text = Jmap_mail.Jmap_email.Get.fetch_text_body_values request in 346 + let fetch_text = Jmap_mail.Email.Get.fetch_text_body_values request in 347 347 check bool "Fetch text body values" true (Option.value ~default:false fetch_text); 348 348 349 - let fetch_html = Jmap_mail.Jmap_email.Get.fetch_html_body_values request in 349 + let fetch_html = Jmap_mail.Email.Get.fetch_html_body_values request in 350 350 check bool "Fetch HTML body values" true (Option.value ~default:false fetch_html); 351 351 352 - let fetch_all = Jmap_mail.Jmap_email.Get.fetch_all_body_values request in 352 + let fetch_all = Jmap_mail.Email.Get.fetch_all_body_values request in 353 353 check bool "Fetch all body values is false" false (Option.value ~default:true fetch_all); 354 354 355 - let max_bytes = Jmap_mail.Jmap_email.Get.max_body_value_bytes request in 355 + let max_bytes = Jmap_mail.Email.Get.max_body_value_bytes request in 356 356 check bool "Max body value bytes present" true (Option.is_some max_bytes); 357 357 check int "Max bytes is 32768" 32768 358 - (Jmap_core.Jmap_primitives.UnsignedInt.to_int (Option.get max_bytes)) 358 + (Jmap_core.Primitives.UnsignedInt.to_int (Option.get max_bytes)) 359 359 360 360 let test_email_get_response () = 361 361 let json = load_json "data/mail/email_get_response.json" in 362 - let response = Jmap_mail.Jmap_email.Get.response_of_json json in 362 + let response = Jmap_mail.Email.Get.response_of_json json in 363 363 364 364 (* Validate response metadata *) 365 - let account_id = Jmap_core.Jmap_standard_methods.Get.response_account_id response in 366 - check string "Response account ID" "u123456" (Jmap_core.Jmap_id.to_string account_id); 365 + let account_id = Jmap_core.Standard_methods.Get.response_account_id response in 366 + check string "Response account ID" "u123456" (Jmap_core.Id.to_string account_id); 367 367 368 - let state = Jmap_core.Jmap_standard_methods.Get.state response in 368 + let state = Jmap_core.Standard_methods.Get.state response in 369 369 check string "Response state" "e42:100" state; 370 370 371 371 (* Validate emails list *) 372 - let emails = Jmap_core.Jmap_standard_methods.Get.list response in 372 + let emails = Jmap_core.Standard_methods.Get.list response in 373 373 check int "Two emails returned" 2 (List.length emails); 374 374 375 375 (* Test first email (e001) *) 376 376 let email1 = List.nth emails 0 in 377 - check string "Email 1 ID" "e001" (Jmap_core.Jmap_id.to_string (Jmap_mail.Jmap_email.id email1)); 378 - check string "Email 1 thread ID" "t001" (Jmap_core.Jmap_id.to_string (Jmap_mail.Jmap_email.thread_id email1)); 377 + check string "Email 1 ID" "e001" (Jmap_core.Id.to_string (Jmap_mail.Email.id email1)); 378 + check string "Email 1 thread ID" "t001" (Jmap_core.Id.to_string (Jmap_mail.Email.thread_id email1)); 379 379 check string "Email 1 subject" "Project Update Q4 2025" 380 - (Option.get (Jmap_mail.Jmap_email.subject email1)); 380 + (Option.get (Jmap_mail.Email.subject email1)); 381 381 check int "Email 1 size" 15234 382 - (Jmap_core.Jmap_primitives.UnsignedInt.to_int (Jmap_mail.Jmap_email.size email1)); 383 - check bool "Email 1 has no attachment" false (Jmap_mail.Jmap_email.has_attachment email1); 382 + (Jmap_core.Primitives.UnsignedInt.to_int (Jmap_mail.Email.size email1)); 383 + check bool "Email 1 has no attachment" false (Jmap_mail.Email.has_attachment email1); 384 384 385 385 (* Test email 1 from address *) 386 - let from1 = Option.get (Jmap_mail.Jmap_email.from email1) in 386 + let from1 = Option.get (Jmap_mail.Email.from email1) in 387 387 check int "Email 1 has one from address" 1 (List.length from1); 388 388 let from_addr = List.nth from1 0 in 389 389 check string "Email 1 from name" "Bob Smith" 390 - (Option.get (Jmap_mail.Jmap_email.EmailAddress.name from_addr)); 390 + (Option.get (Jmap_mail.Email.EmailAddress.name from_addr)); 391 391 check string "Email 1 from email" "bob@example.com" 392 - (Jmap_mail.Jmap_email.EmailAddress.email from_addr); 392 + (Jmap_mail.Email.EmailAddress.email from_addr); 393 393 394 394 (* Test email 1 to addresses *) 395 - let to1 = Option.get (Jmap_mail.Jmap_email.to_ email1) in 395 + let to1 = Option.get (Jmap_mail.Email.to_ email1) in 396 396 check int "Email 1 has one to address" 1 (List.length to1); 397 397 let to_addr = List.nth to1 0 in 398 398 check string "Email 1 to name" "Alice Jones" 399 - (Option.get (Jmap_mail.Jmap_email.EmailAddress.name to_addr)); 399 + (Option.get (Jmap_mail.Email.EmailAddress.name to_addr)); 400 400 check string "Email 1 to email" "alice@example.com" 401 - (Jmap_mail.Jmap_email.EmailAddress.email to_addr); 401 + (Jmap_mail.Email.EmailAddress.email to_addr); 402 402 403 403 (* Test email 1 keywords *) 404 - let keywords1 = Jmap_mail.Jmap_email.keywords email1 in 404 + let keywords1 = Jmap_mail.Email.keywords email1 in 405 405 check bool "Email 1 has $seen keyword" true 406 406 (List.mem_assoc "$seen" keywords1); 407 407 check bool "Email 1 $seen is true" true ··· 409 409 410 410 (* Test second email (e002) *) 411 411 let email2 = List.nth emails 1 in 412 - check string "Email 2 ID" "e002" (Jmap_core.Jmap_id.to_string (Jmap_mail.Jmap_email.id email2)); 412 + check string "Email 2 ID" "e002" (Jmap_core.Id.to_string (Jmap_mail.Email.id email2)); 413 413 check string "Email 2 subject" "Re: Technical Requirements Review" 414 - (Option.get (Jmap_mail.Jmap_email.subject email2)); 414 + (Option.get (Jmap_mail.Email.subject email2)); 415 415 416 416 (* Test email 2 to addresses (multiple recipients) *) 417 - let to2 = Option.get (Jmap_mail.Jmap_email.to_ email2) in 417 + let to2 = Option.get (Jmap_mail.Email.to_ email2) in 418 418 check int "Email 2 has two to addresses" 2 (List.length to2); 419 419 420 420 (* Test email 2 keywords *) 421 - let keywords2 = Jmap_mail.Jmap_email.keywords email2 in 421 + let keywords2 = Jmap_mail.Email.keywords email2 in 422 422 check bool "Email 2 has $seen keyword" true 423 423 (List.mem_assoc "$seen" keywords2); 424 424 check bool "Email 2 has $flagged keyword" true 425 425 (List.mem_assoc "$flagged" keywords2); 426 426 427 427 (* Test email 2 replyTo *) 428 - let reply_to2 = Jmap_mail.Jmap_email.reply_to email2 in 428 + let reply_to2 = Jmap_mail.Email.reply_to email2 in 429 429 check bool "Email 2 has replyTo" true (Option.is_some reply_to2); 430 430 let reply_to_list = Option.get reply_to2 in 431 431 check int "Email 2 has one replyTo address" 1 (List.length reply_to_list); 432 432 let reply_addr = List.nth reply_to_list 0 in 433 433 check string "Email 2 replyTo email" "support@company.com" 434 - (Jmap_mail.Jmap_email.EmailAddress.email reply_addr); 434 + (Jmap_mail.Email.EmailAddress.email reply_addr); 435 435 436 436 (* Validate notFound is empty *) 437 - let not_found = Jmap_core.Jmap_standard_methods.Get.not_found response in 437 + let not_found = Jmap_core.Standard_methods.Get.not_found response in 438 438 check int "No emails not found" 0 (List.length not_found) 439 439 440 440 let test_email_get_full_response () = 441 441 let json = load_json "data/mail/email_get_full_response.json" in 442 - let response = Jmap_mail.Jmap_email.Get.response_of_json json in 442 + let response = Jmap_mail.Email.Get.response_of_json json in 443 443 444 - let emails = Jmap_core.Jmap_standard_methods.Get.list response in 444 + let emails = Jmap_core.Standard_methods.Get.list response in 445 445 check int "One email returned" 1 (List.length emails); 446 446 447 447 let email = List.nth emails 0 in 448 448 449 449 (* Validate basic fields *) 450 - check string "Email ID" "e001" (Jmap_core.Jmap_id.to_string (Jmap_mail.Jmap_email.id email)); 451 - check bool "Has attachment" true (Jmap_mail.Jmap_email.has_attachment email); 450 + check string "Email ID" "e001" (Jmap_core.Id.to_string (Jmap_mail.Email.id email)); 451 + check bool "Has attachment" true (Jmap_mail.Email.has_attachment email); 452 452 453 453 (* Validate bodyStructure (multipart/mixed with nested multipart/alternative) *) 454 - let body_structure = Jmap_mail.Jmap_email.body_structure email in 454 + let body_structure = Jmap_mail.Email.body_structure email in 455 455 check bool "Has bodyStructure" true (Option.is_some body_structure); 456 456 457 457 let root_part = Option.get body_structure in 458 458 check string "Root type is multipart/mixed" "multipart/mixed" 459 - (Jmap_mail.Jmap_email.BodyPart.type_ root_part); 459 + (Jmap_mail.Email.BodyPart.type_ root_part); 460 460 461 - let sub_parts = Jmap_mail.Jmap_email.BodyPart.sub_parts root_part in 461 + let sub_parts = Jmap_mail.Email.BodyPart.sub_parts root_part in 462 462 check bool "Root has subParts" true (Option.is_some sub_parts); 463 463 let parts_list = Option.get sub_parts in 464 464 check int "Root has 2 subParts" 2 (List.length parts_list); ··· 466 466 (* First subpart: multipart/alternative *) 467 467 let alt_part = List.nth parts_list 0 in 468 468 check string "First subpart is multipart/alternative" "multipart/alternative" 469 - (Jmap_mail.Jmap_email.BodyPart.type_ alt_part); 469 + (Jmap_mail.Email.BodyPart.type_ alt_part); 470 470 471 - let alt_sub_parts = Option.get (Jmap_mail.Jmap_email.BodyPart.sub_parts alt_part) in 471 + let alt_sub_parts = Option.get (Jmap_mail.Email.BodyPart.sub_parts alt_part) in 472 472 check int "Alternative has 2 subParts" 2 (List.length alt_sub_parts); 473 473 474 474 (* Text/plain part *) 475 475 let text_part = List.nth alt_sub_parts 0 in 476 - check string "Text part type" "text/plain" (Jmap_mail.Jmap_email.BodyPart.type_ text_part); 476 + check string "Text part type" "text/plain" (Jmap_mail.Email.BodyPart.type_ text_part); 477 477 check string "Text part charset" "utf-8" 478 - (Option.get (Jmap_mail.Jmap_email.BodyPart.charset text_part)); 479 - check string "Text part ID" "1" (Option.get (Jmap_mail.Jmap_email.BodyPart.part_id text_part)); 478 + (Option.get (Jmap_mail.Email.BodyPart.charset text_part)); 479 + check string "Text part ID" "1" (Option.get (Jmap_mail.Email.BodyPart.part_id text_part)); 480 480 check int "Text part size" 2134 481 - (Jmap_core.Jmap_primitives.UnsignedInt.to_int (Jmap_mail.Jmap_email.BodyPart.size text_part)); 481 + (Jmap_core.Primitives.UnsignedInt.to_int (Jmap_mail.Email.BodyPart.size text_part)); 482 482 483 483 (* Text/html part *) 484 484 let html_part = List.nth alt_sub_parts 1 in 485 - check string "HTML part type" "text/html" (Jmap_mail.Jmap_email.BodyPart.type_ html_part); 486 - check string "HTML part ID" "2" (Option.get (Jmap_mail.Jmap_email.BodyPart.part_id html_part)); 485 + check string "HTML part type" "text/html" (Jmap_mail.Email.BodyPart.type_ html_part); 486 + check string "HTML part ID" "2" (Option.get (Jmap_mail.Email.BodyPart.part_id html_part)); 487 487 check int "HTML part size" 4567 488 - (Jmap_core.Jmap_primitives.UnsignedInt.to_int (Jmap_mail.Jmap_email.BodyPart.size html_part)); 488 + (Jmap_core.Primitives.UnsignedInt.to_int (Jmap_mail.Email.BodyPart.size html_part)); 489 489 490 490 (* Attachment part *) 491 491 let attach_part = List.nth parts_list 1 in 492 492 check string "Attachment type" "application/pdf" 493 - (Jmap_mail.Jmap_email.BodyPart.type_ attach_part); 493 + (Jmap_mail.Email.BodyPart.type_ attach_part); 494 494 check string "Attachment name" "Q4_Report.pdf" 495 - (Option.get (Jmap_mail.Jmap_email.BodyPart.name attach_part)); 495 + (Option.get (Jmap_mail.Email.BodyPart.name attach_part)); 496 496 check string "Attachment disposition" "attachment" 497 - (Option.get (Jmap_mail.Jmap_email.BodyPart.disposition attach_part)); 497 + (Option.get (Jmap_mail.Email.BodyPart.disposition attach_part)); 498 498 check string "Attachment part ID" "3" 499 - (Option.get (Jmap_mail.Jmap_email.BodyPart.part_id attach_part)); 499 + (Option.get (Jmap_mail.Email.BodyPart.part_id attach_part)); 500 500 check int "Attachment size" 8533 501 - (Jmap_core.Jmap_primitives.UnsignedInt.to_int (Jmap_mail.Jmap_email.BodyPart.size attach_part)); 501 + (Jmap_core.Primitives.UnsignedInt.to_int (Jmap_mail.Email.BodyPart.size attach_part)); 502 502 503 503 (* Validate textBody *) 504 - let text_body = Jmap_mail.Jmap_email.text_body email in 504 + let text_body = Jmap_mail.Email.text_body email in 505 505 check bool "Has textBody" true (Option.is_some text_body); 506 506 let text_body_list = Option.get text_body in 507 507 check int "One textBody part" 1 (List.length text_body_list); 508 508 let text_body_part = List.nth text_body_list 0 in 509 509 check string "textBody part ID" "1" 510 - (Option.get (Jmap_mail.Jmap_email.BodyPart.part_id text_body_part)); 510 + (Option.get (Jmap_mail.Email.BodyPart.part_id text_body_part)); 511 511 check string "textBody type" "text/plain" 512 - (Jmap_mail.Jmap_email.BodyPart.type_ text_body_part); 512 + (Jmap_mail.Email.BodyPart.type_ text_body_part); 513 513 514 514 (* Validate htmlBody *) 515 - let html_body = Jmap_mail.Jmap_email.html_body email in 515 + let html_body = Jmap_mail.Email.html_body email in 516 516 check bool "Has htmlBody" true (Option.is_some html_body); 517 517 let html_body_list = Option.get html_body in 518 518 check int "One htmlBody part" 1 (List.length html_body_list); 519 519 let html_body_part = List.nth html_body_list 0 in 520 520 check string "htmlBody part ID" "2" 521 - (Option.get (Jmap_mail.Jmap_email.BodyPart.part_id html_body_part)); 521 + (Option.get (Jmap_mail.Email.BodyPart.part_id html_body_part)); 522 522 check string "htmlBody type" "text/html" 523 - (Jmap_mail.Jmap_email.BodyPart.type_ html_body_part); 523 + (Jmap_mail.Email.BodyPart.type_ html_body_part); 524 524 525 525 (* Validate attachments *) 526 - let attachments = Jmap_mail.Jmap_email.attachments email in 526 + let attachments = Jmap_mail.Email.attachments email in 527 527 check bool "Has attachments" true (Option.is_some attachments); 528 528 let attachments_list = Option.get attachments in 529 529 check int "One attachment" 1 (List.length attachments_list); 530 530 let attachment = List.nth attachments_list 0 in 531 531 check string "Attachment name" "Q4_Report.pdf" 532 - (Option.get (Jmap_mail.Jmap_email.BodyPart.name attachment)); 532 + (Option.get (Jmap_mail.Email.BodyPart.name attachment)); 533 533 534 534 (* Validate bodyValues *) 535 - let body_values = Jmap_mail.Jmap_email.body_values email in 535 + let body_values = Jmap_mail.Email.body_values email in 536 536 check bool "Has bodyValues" true (Option.is_some body_values); 537 537 let values_list = Option.get body_values in 538 538 check int "Two bodyValues" 2 (List.length values_list); ··· 540 540 (* Text body value *) 541 541 check bool "Has bodyValue for part 1" true (List.mem_assoc "1" values_list); 542 542 let text_value = List.assoc "1" values_list in 543 - let text_content = Jmap_mail.Jmap_email.BodyValue.value text_value in 543 + let text_content = Jmap_mail.Email.BodyValue.value text_value in 544 544 check bool "Text content starts with 'Hi Alice'" true 545 545 (String.starts_with ~prefix:"Hi Alice" text_content); 546 546 check bool "Text not truncated" false 547 - (Jmap_mail.Jmap_email.BodyValue.is_truncated text_value); 547 + (Jmap_mail.Email.BodyValue.is_truncated text_value); 548 548 check bool "Text no encoding problem" false 549 - (Jmap_mail.Jmap_email.BodyValue.is_encoding_problem text_value); 549 + (Jmap_mail.Email.BodyValue.is_encoding_problem text_value); 550 550 551 551 (* HTML body value *) 552 552 check bool "Has bodyValue for part 2" true (List.mem_assoc "2" values_list); 553 553 let html_value = List.assoc "2" values_list in 554 - let html_content = Jmap_mail.Jmap_email.BodyValue.value html_value in 554 + let html_content = Jmap_mail.Email.BodyValue.value html_value in 555 555 check bool "HTML content starts with '<html>'" true 556 556 (String.starts_with ~prefix:"<html>" html_content); 557 557 check bool "HTML not truncated" false 558 - (Jmap_mail.Jmap_email.BodyValue.is_truncated html_value) 558 + (Jmap_mail.Email.BodyValue.is_truncated html_value) 559 559 560 560 let test_email_query_request () = 561 561 let json = load_json "data/mail/email_query_request.json" in 562 - let request = Jmap_mail.Jmap_email.Query.request_of_json json in 562 + let request = Jmap_mail.Email.Query.request_of_json json in 563 563 564 564 (* Validate account_id *) 565 - let account_id = Jmap_mail.Jmap_email.Query.account_id request in 566 - check string "Account ID" "u123456" (Jmap_core.Jmap_id.to_string account_id); 565 + let account_id = Jmap_mail.Email.Query.account_id request in 566 + check string "Account ID" "u123456" (Jmap_core.Id.to_string account_id); 567 567 568 568 (* Validate limit *) 569 - let limit = Jmap_mail.Jmap_email.Query.limit request in 569 + let limit = Jmap_mail.Email.Query.limit request in 570 570 check bool "Has limit" true (Option.is_some limit); 571 571 check int "Limit is 50" 50 572 - (Jmap_core.Jmap_primitives.UnsignedInt.to_int (Option.get limit)); 572 + (Jmap_core.Primitives.UnsignedInt.to_int (Option.get limit)); 573 573 574 574 (* Validate calculateTotal *) 575 - let calc_total = Jmap_mail.Jmap_email.Query.calculate_total request in 575 + let calc_total = Jmap_mail.Email.Query.calculate_total request in 576 576 check bool "Calculate total is true" true (Option.value ~default:false calc_total); 577 577 578 578 (* Validate collapseThreads *) 579 - let collapse = Jmap_mail.Jmap_email.Query.collapse_threads request in 579 + let collapse = Jmap_mail.Email.Query.collapse_threads request in 580 580 check bool "Collapse threads is false" false (Option.value ~default:true collapse); 581 581 582 582 (* Validate position *) 583 - let position = Jmap_mail.Jmap_email.Query.position request in 583 + let position = Jmap_mail.Email.Query.position request in 584 584 check bool "Has position" true (Option.is_some position); 585 585 check int "Position is 0" 0 586 - (Jmap_core.Jmap_primitives.Int53.to_int (Option.get position)) 586 + (Jmap_core.Primitives.Int53.to_int (Option.get position)) 587 587 588 588 let test_email_query_response () = 589 589 let json = load_json "data/mail/email_query_response.json" in 590 - let response = Jmap_mail.Jmap_email.Query.response_of_json json in 590 + let response = Jmap_mail.Email.Query.response_of_json json in 591 591 592 592 (* Validate account_id *) 593 - let account_id = Jmap_core.Jmap_standard_methods.Query.response_account_id response in 594 - check string "Account ID" "u123456" (Jmap_core.Jmap_id.to_string account_id); 593 + let account_id = Jmap_core.Standard_methods.Query.response_account_id response in 594 + check string "Account ID" "u123456" (Jmap_core.Id.to_string account_id); 595 595 596 596 (* Validate query state *) 597 - let query_state = Jmap_core.Jmap_standard_methods.Query.query_state response in 597 + let query_state = Jmap_core.Standard_methods.Query.query_state response in 598 598 check string "Query state" "eq42:100" query_state; 599 599 600 600 (* Validate can calculate changes *) 601 - let can_calc = Jmap_core.Jmap_standard_methods.Query.can_calculate_changes response in 601 + let can_calc = Jmap_core.Standard_methods.Query.can_calculate_changes response in 602 602 check bool "Can calculate changes" true can_calc; 603 603 604 604 (* Validate position *) 605 - let position = Jmap_core.Jmap_standard_methods.Query.response_position response in 606 - check int "Position is 0" 0 (Jmap_core.Jmap_primitives.UnsignedInt.to_int position); 605 + let position = Jmap_core.Standard_methods.Query.response_position response in 606 + check int "Position is 0" 0 (Jmap_core.Primitives.UnsignedInt.to_int position); 607 607 608 608 (* Validate IDs *) 609 - let ids = Jmap_core.Jmap_standard_methods.Query.ids response in 609 + let ids = Jmap_core.Standard_methods.Query.ids response in 610 610 check int "Five IDs returned" 5 (List.length ids); 611 - check string "First ID" "e015" (Jmap_core.Jmap_id.to_string (List.nth ids 0)); 612 - check string "Last ID" "e005" (Jmap_core.Jmap_id.to_string (List.nth ids 4)); 611 + check string "First ID" "e015" (Jmap_core.Id.to_string (List.nth ids 0)); 612 + check string "Last ID" "e005" (Jmap_core.Id.to_string (List.nth ids 4)); 613 613 614 614 (* Validate total *) 615 - let total = Jmap_core.Jmap_standard_methods.Query.total response in 615 + let total = Jmap_core.Standard_methods.Query.total response in 616 616 check bool "Has total" true (Option.is_some total); 617 617 check int "Total is 5" 5 618 - (Jmap_core.Jmap_primitives.UnsignedInt.to_int (Option.get total)) 618 + (Jmap_core.Primitives.UnsignedInt.to_int (Option.get total)) 619 619 620 620 let test_email_set_request () = 621 621 let json = load_json "data/mail/email_set_request.json" in 622 - let request = Jmap_mail.Jmap_email.Set.request_of_json json in 622 + let request = Jmap_mail.Email.Set.request_of_json json in 623 623 624 624 (* Validate account_id *) 625 - let account_id = Jmap_core.Jmap_standard_methods.Set.account_id request in 626 - check string "Account ID" "u123456" (Jmap_core.Jmap_id.to_string account_id); 625 + let account_id = Jmap_core.Standard_methods.Set.account_id request in 626 + check string "Account ID" "u123456" (Jmap_core.Id.to_string account_id); 627 627 628 628 (* Validate ifInState *) 629 - let if_in_state = Jmap_core.Jmap_standard_methods.Set.if_in_state request in 629 + let if_in_state = Jmap_core.Standard_methods.Set.if_in_state request in 630 630 check bool "Has ifInState" true (Option.is_some if_in_state); 631 631 check string "ifInState value" "e42:100" (Option.get if_in_state); 632 632 633 633 (* Validate create *) 634 - let create = Jmap_core.Jmap_standard_methods.Set.create request in 634 + let create = Jmap_core.Standard_methods.Set.create request in 635 635 check bool "Has create" true (Option.is_some create); 636 636 let create_list = Option.get create in 637 637 check int "One email to create" 1 (List.length create_list); 638 638 let (create_id, _email) = List.nth create_list 0 in 639 - check string "Create ID" "temp-email-1" (Jmap_core.Jmap_id.to_string create_id); 639 + check string "Create ID" "temp-email-1" (Jmap_core.Id.to_string create_id); 640 640 641 641 (* Validate update *) 642 - let update = Jmap_core.Jmap_standard_methods.Set.update request in 642 + let update = Jmap_core.Standard_methods.Set.update request in 643 643 check bool "Has update" true (Option.is_some update); 644 644 let update_list = Option.get update in 645 645 check int "Two emails to update" 2 (List.length update_list); 646 646 647 647 (* Validate destroy *) 648 - let destroy = Jmap_core.Jmap_standard_methods.Set.destroy request in 648 + let destroy = Jmap_core.Standard_methods.Set.destroy request in 649 649 check bool "Has destroy" true (Option.is_some destroy); 650 650 let destroy_list = Option.get destroy in 651 651 check int "One email to destroy" 1 (List.length destroy_list); 652 - check string "Destroy ID" "e099" (Jmap_core.Jmap_id.to_string (List.nth destroy_list 0)) 652 + check string "Destroy ID" "e099" (Jmap_core.Id.to_string (List.nth destroy_list 0)) 653 653 654 654 let test_email_set_response () = 655 655 let json = load_json "data/mail/email_set_response.json" in 656 - let response = Jmap_mail.Jmap_email.Set.response_of_json json in 656 + let response = Jmap_mail.Email.Set.response_of_json json in 657 657 658 658 (* Validate account_id *) 659 - let account_id = Jmap_core.Jmap_standard_methods.Set.response_account_id response in 660 - check string "Account ID" "u123456" (Jmap_core.Jmap_id.to_string account_id); 659 + let account_id = Jmap_core.Standard_methods.Set.response_account_id response in 660 + check string "Account ID" "u123456" (Jmap_core.Id.to_string account_id); 661 661 662 662 (* Validate states *) 663 - let old_state = Jmap_core.Jmap_standard_methods.Set.old_state response in 663 + let old_state = Jmap_core.Standard_methods.Set.old_state response in 664 664 check bool "Has old state" true (Option.is_some old_state); 665 665 check string "Old state" "e42:100" (Option.get old_state); 666 666 667 - let new_state = Jmap_core.Jmap_standard_methods.Set.new_state response in 667 + let new_state = Jmap_core.Standard_methods.Set.new_state response in 668 668 check string "New state" "e42:103" new_state; 669 669 670 670 (* Validate created *) 671 - let created = Jmap_core.Jmap_standard_methods.Set.created response in 671 + let created = Jmap_core.Standard_methods.Set.created response in 672 672 check bool "Has created" true (Option.is_some created); 673 673 let created_list = Option.get created in 674 674 check int "One email created" 1 (List.length created_list); 675 675 let (temp_id, email) = List.nth created_list 0 in 676 - check string "Created temp ID" "temp-email-1" (Jmap_core.Jmap_id.to_string temp_id); 677 - check string "Created email ID" "e101" (Jmap_core.Jmap_id.to_string (Jmap_mail.Jmap_email.id email)); 676 + check string "Created temp ID" "temp-email-1" (Jmap_core.Id.to_string temp_id); 677 + check string "Created email ID" "e101" (Jmap_core.Id.to_string (Jmap_mail.Email.id email)); 678 678 check string "Created thread ID" "t050" 679 - (Jmap_core.Jmap_id.to_string (Jmap_mail.Jmap_email.thread_id email)); 679 + (Jmap_core.Id.to_string (Jmap_mail.Email.thread_id email)); 680 680 681 681 (* Validate updated *) 682 - let updated = Jmap_core.Jmap_standard_methods.Set.updated response in 682 + let updated = Jmap_core.Standard_methods.Set.updated response in 683 683 check bool "Has updated" true (Option.is_some updated); 684 684 let updated_map = Option.get updated in 685 685 check int "Two emails updated" 2 (List.length updated_map); 686 686 687 687 (* Validate destroyed *) 688 - let destroyed = Jmap_core.Jmap_standard_methods.Set.destroyed response in 688 + let destroyed = Jmap_core.Standard_methods.Set.destroyed response in 689 689 check bool "Has destroyed" true (Option.is_some destroyed); 690 690 let destroyed_list = Option.get destroyed in 691 691 check int "One email destroyed" 1 (List.length destroyed_list); 692 - check string "Destroyed ID" "e099" (Jmap_core.Jmap_id.to_string (List.nth destroyed_list 0)) 692 + check string "Destroyed ID" "e099" (Jmap_core.Id.to_string (List.nth destroyed_list 0)) 693 693 694 694 let test_email_import_request () = 695 695 let json = load_json "data/mail/email_import_request.json" in 696 - let request = Jmap_mail.Jmap_email.Import.request_of_json json in 696 + let request = Jmap_mail.Email.Import.request_of_json json in 697 697 698 698 (* Validate account_id *) 699 - let account_id = Jmap_mail.Jmap_email.Import.account_id request in 700 - check string "Account ID" "u123456" (Jmap_core.Jmap_id.to_string account_id); 699 + let account_id = Jmap_mail.Email.Import.account_id request in 700 + check string "Account ID" "u123456" (Jmap_core.Id.to_string account_id); 701 701 702 702 (* Validate ifInState *) 703 - let if_in_state = Jmap_mail.Jmap_email.Import.if_in_state request in 703 + let if_in_state = Jmap_mail.Email.Import.if_in_state request in 704 704 check bool "Has ifInState" true (Option.is_some if_in_state); 705 705 check string "ifInState value" "e42:103" (Option.get if_in_state); 706 706 707 707 (* Validate emails *) 708 - let emails = Jmap_mail.Jmap_email.Import.emails request in 708 + let emails = Jmap_mail.Email.Import.emails request in 709 709 check int "Two emails to import" 2 (List.length emails); 710 710 711 711 let (import_id1, import_email1) = List.nth emails 0 in 712 - check string "First import ID" "temp-import-1" (Jmap_core.Jmap_id.to_string import_id1); 713 - let blob_id1 = Jmap_mail.Jmap_email.Import.import_blob_id import_email1 in 712 + check string "First import ID" "temp-import-1" (Jmap_core.Id.to_string import_id1); 713 + let blob_id1 = Jmap_mail.Email.Import.import_blob_id import_email1 in 714 714 check string "First blob ID starts correctly" "Gb5f55i6" 715 - (String.sub (Jmap_core.Jmap_id.to_string blob_id1) 0 8); 715 + (String.sub (Jmap_core.Id.to_string blob_id1) 0 8); 716 716 717 - let keywords1 = Jmap_mail.Jmap_email.Import.import_keywords import_email1 in 717 + let keywords1 = Jmap_mail.Email.Import.import_keywords import_email1 in 718 718 check bool "First email has $seen keyword" true 719 719 (List.mem_assoc "$seen" keywords1) 720 720 721 721 let test_email_import_response () = 722 722 let json = load_json "data/mail/email_import_response.json" in 723 - let response = Jmap_mail.Jmap_email.Import.response_of_json json in 723 + let response = Jmap_mail.Email.Import.response_of_json json in 724 724 725 725 (* Validate account_id *) 726 - let account_id = Jmap_mail.Jmap_email.Import.response_account_id response in 727 - check string "Account ID" "u123456" (Jmap_core.Jmap_id.to_string account_id); 726 + let account_id = Jmap_mail.Email.Import.response_account_id response in 727 + check string "Account ID" "u123456" (Jmap_core.Id.to_string account_id); 728 728 729 729 (* Validate states *) 730 - let old_state = Jmap_mail.Jmap_email.Import.old_state response in 730 + let old_state = Jmap_mail.Email.Import.old_state response in 731 731 check bool "Has old state" true (Option.is_some old_state); 732 732 check string "Old state" "e42:103" (Option.get old_state); 733 733 734 - let new_state = Jmap_mail.Jmap_email.Import.new_state response in 734 + let new_state = Jmap_mail.Email.Import.new_state response in 735 735 check string "New state" "e42:105" new_state; 736 736 737 737 (* Validate created *) 738 - let created = Jmap_mail.Jmap_email.Import.created response in 738 + let created = Jmap_mail.Email.Import.created response in 739 739 check bool "Has created" true (Option.is_some created); 740 740 let created_list = Option.get created in 741 741 check int "Two emails imported" 2 (List.length created_list); 742 742 743 743 let (temp_id1, email1) = List.nth created_list 0 in 744 - check string "First temp ID" "temp-import-1" (Jmap_core.Jmap_id.to_string temp_id1); 745 - check string "First email ID" "e102" (Jmap_core.Jmap_id.to_string (Jmap_mail.Jmap_email.id email1)); 744 + check string "First temp ID" "temp-import-1" (Jmap_core.Id.to_string temp_id1); 745 + check string "First email ID" "e102" (Jmap_core.Id.to_string (Jmap_mail.Email.id email1)); 746 746 check string "First thread ID" "t051" 747 - (Jmap_core.Jmap_id.to_string (Jmap_mail.Jmap_email.thread_id email1)); 747 + (Jmap_core.Id.to_string (Jmap_mail.Email.thread_id email1)); 748 748 749 749 let (temp_id2, email2) = List.nth created_list 1 in 750 - check string "Second temp ID" "temp-import-2" (Jmap_core.Jmap_id.to_string temp_id2); 751 - check string "Second email ID" "e103" (Jmap_core.Jmap_id.to_string (Jmap_mail.Jmap_email.id email2)) 750 + check string "Second temp ID" "temp-import-2" (Jmap_core.Id.to_string temp_id2); 751 + check string "Second email ID" "e103" (Jmap_core.Id.to_string (Jmap_mail.Email.id email2)) 752 752 753 753 let test_email_parse_request () = 754 754 let json = load_json "data/mail/email_parse_request.json" in 755 - let request = Jmap_mail.Jmap_email.Parse.request_of_json json in 755 + let request = Jmap_mail.Email.Parse.request_of_json json in 756 756 757 757 (* Validate account_id *) 758 - let account_id = Jmap_mail.Jmap_email.Parse.account_id request in 759 - check string "Account ID" "u123456" (Jmap_core.Jmap_id.to_string account_id); 758 + let account_id = Jmap_mail.Email.Parse.account_id request in 759 + check string "Account ID" "u123456" (Jmap_core.Id.to_string account_id); 760 760 761 761 (* Validate blob_ids *) 762 - let blob_ids = Jmap_mail.Jmap_email.Parse.blob_ids request in 762 + let blob_ids = Jmap_mail.Email.Parse.blob_ids request in 763 763 check int "One blob ID" 1 (List.length blob_ids); 764 764 let blob_id = List.nth blob_ids 0 in 765 765 check string "Blob ID starts correctly" "Gb5f77k8" 766 - (String.sub (Jmap_core.Jmap_id.to_string blob_id) 0 8); 766 + (String.sub (Jmap_core.Id.to_string blob_id) 0 8); 767 767 768 768 (* Validate fetch options *) 769 - let fetch_text = Jmap_mail.Jmap_email.Parse.fetch_text_body_values request in 769 + let fetch_text = Jmap_mail.Email.Parse.fetch_text_body_values request in 770 770 check bool "Fetch text body values" true (Option.value ~default:false fetch_text); 771 771 772 - let fetch_html = Jmap_mail.Jmap_email.Parse.fetch_html_body_values request in 772 + let fetch_html = Jmap_mail.Email.Parse.fetch_html_body_values request in 773 773 check bool "Fetch HTML body values" true (Option.value ~default:false fetch_html); 774 774 775 - let max_bytes = Jmap_mail.Jmap_email.Parse.max_body_value_bytes request in 775 + let max_bytes = Jmap_mail.Email.Parse.max_body_value_bytes request in 776 776 check bool "Has max bytes" true (Option.is_some max_bytes); 777 777 check int "Max bytes is 16384" 16384 778 - (Jmap_core.Jmap_primitives.UnsignedInt.to_int (Option.get max_bytes)) 778 + (Jmap_core.Primitives.UnsignedInt.to_int (Option.get max_bytes)) 779 779 780 780 let test_email_parse_response () = 781 781 let json = load_json "data/mail/email_parse_response.json" in 782 - let response = Jmap_mail.Jmap_email.Parse.response_of_json json in 782 + let response = Jmap_mail.Email.Parse.response_of_json json in 783 783 784 784 (* Validate account_id *) 785 - let account_id = Jmap_mail.Jmap_email.Parse.response_account_id response in 786 - check string "Account ID" "u123456" (Jmap_core.Jmap_id.to_string account_id); 785 + let account_id = Jmap_mail.Email.Parse.response_account_id response in 786 + check string "Account ID" "u123456" (Jmap_core.Id.to_string account_id); 787 787 788 788 (* Validate parsed *) 789 - let parsed = Jmap_mail.Jmap_email.Parse.parsed response in 789 + let parsed = Jmap_mail.Email.Parse.parsed response in 790 790 check bool "Has parsed emails" true (Option.is_some parsed); 791 791 let parsed_list = Option.get parsed in 792 792 check int "One email parsed" 1 (List.length parsed_list); 793 793 794 794 let (blob_id, email) = List.nth parsed_list 0 in 795 795 check string "Blob ID starts correctly" "Gb5f77k8" 796 - (String.sub (Jmap_core.Jmap_id.to_string blob_id) 0 8); 796 + (String.sub (Jmap_core.Id.to_string blob_id) 0 8); 797 797 798 798 (* Validate parsed email *) 799 799 check string "Subject" "Important Announcement" 800 - (Option.get (Jmap_mail.Jmap_email.subject email)); 801 - check bool "Has no attachment" false (Jmap_mail.Jmap_email.has_attachment email); 800 + (Option.get (Jmap_mail.Email.subject email)); 801 + check bool "Has no attachment" false (Jmap_mail.Email.has_attachment email); 802 802 803 803 (* Validate from *) 804 - let from = Option.get (Jmap_mail.Jmap_email.from email) in 804 + let from = Option.get (Jmap_mail.Email.from email) in 805 805 check int "One from address" 1 (List.length from); 806 806 let from_addr = List.nth from 0 in 807 807 check string "From name" "Charlie Green" 808 - (Option.get (Jmap_mail.Jmap_email.EmailAddress.name from_addr)); 808 + (Option.get (Jmap_mail.Email.EmailAddress.name from_addr)); 809 809 check string "From email" "charlie@company.com" 810 - (Jmap_mail.Jmap_email.EmailAddress.email from_addr); 810 + (Jmap_mail.Email.EmailAddress.email from_addr); 811 811 812 812 (* Validate bodyStructure (simple text/plain) *) 813 - let body_structure = Jmap_mail.Jmap_email.body_structure email in 813 + let body_structure = Jmap_mail.Email.body_structure email in 814 814 check bool "Has bodyStructure" true (Option.is_some body_structure); 815 815 let body_part = Option.get body_structure in 816 - check string "Body type" "text/plain" (Jmap_mail.Jmap_email.BodyPart.type_ body_part); 816 + check string "Body type" "text/plain" (Jmap_mail.Email.BodyPart.type_ body_part); 817 817 check string "Body part ID" "1" 818 - (Option.get (Jmap_mail.Jmap_email.BodyPart.part_id body_part)); 818 + (Option.get (Jmap_mail.Email.BodyPart.part_id body_part)); 819 819 check int "Body size" 1523 820 - (Jmap_core.Jmap_primitives.UnsignedInt.to_int (Jmap_mail.Jmap_email.BodyPart.size body_part)); 820 + (Jmap_core.Primitives.UnsignedInt.to_int (Jmap_mail.Email.BodyPart.size body_part)); 821 821 822 822 (* Validate textBody *) 823 - let text_body = Jmap_mail.Jmap_email.text_body email in 823 + let text_body = Jmap_mail.Email.text_body email in 824 824 check bool "Has textBody" true (Option.is_some text_body); 825 825 let text_body_list = Option.get text_body in 826 826 check int "One textBody part" 1 (List.length text_body_list); 827 827 828 828 (* Validate htmlBody is empty *) 829 - let html_body = Jmap_mail.Jmap_email.html_body email in 829 + let html_body = Jmap_mail.Email.html_body email in 830 830 check bool "Has htmlBody" true (Option.is_some html_body); 831 831 let html_body_list = Option.get html_body in 832 832 check int "No htmlBody parts" 0 (List.length html_body_list); 833 833 834 834 (* Validate attachments is empty *) 835 - let attachments = Jmap_mail.Jmap_email.attachments email in 835 + let attachments = Jmap_mail.Email.attachments email in 836 836 check bool "Has attachments" true (Option.is_some attachments); 837 837 let attachments_list = Option.get attachments in 838 838 check int "No attachments" 0 (List.length attachments_list); 839 839 840 840 (* Validate bodyValues *) 841 - let body_values = Jmap_mail.Jmap_email.body_values email in 841 + let body_values = Jmap_mail.Email.body_values email in 842 842 check bool "Has bodyValues" true (Option.is_some body_values); 843 843 let values_list = Option.get body_values in 844 844 check int "One bodyValue" 1 (List.length values_list); 845 845 check bool "Has bodyValue for part 1" true (List.mem_assoc "1" values_list); 846 846 let body_value = List.assoc "1" values_list in 847 - let content = Jmap_mail.Jmap_email.BodyValue.value body_value in 847 + let content = Jmap_mail.Email.BodyValue.value body_value in 848 848 check bool "Content starts with 'Team'" true 849 849 (String.starts_with ~prefix:"Team" content); 850 850 851 851 (* Validate notParsable and notFound are empty *) 852 - let not_parsable = Jmap_mail.Jmap_email.Parse.not_parsable response in 852 + let not_parsable = Jmap_mail.Email.Parse.not_parsable response in 853 853 check bool "Has notParsable" true (Option.is_some not_parsable); 854 854 check int "No unparsable blobs" 0 (List.length (Option.get not_parsable)); 855 855 856 - let not_found = Jmap_mail.Jmap_email.Parse.not_found response in 856 + let not_found = Jmap_mail.Email.Parse.not_found response in 857 857 check bool "Has notFound" true (Option.is_some not_found); 858 858 check int "No blobs not found" 0 (List.length (Option.get not_found)) 859 859
+69
stack/jmap/test/test_unified_api.ml
··· 1 + (** Test demonstrating the unified Jmap API *) 2 + 3 + let test_module_aliases () = 4 + (* Using the clean, ergonomic unified Jmap module *) 5 + let id1 = Jmap.Id.of_string "test123" in 6 + let id2 = Jmap.Id.of_string "test456" in 7 + 8 + assert (Jmap.Id.to_string id1 = "test123"); 9 + assert (Jmap.Id.to_string id2 = "test456"); 10 + 11 + (* Test capability creation *) 12 + let caps = [Jmap.Capability.core; Jmap.Capability.mail] in 13 + assert (List.length caps = 2); 14 + 15 + (* Test primitives *) 16 + let limit = Jmap.Primitives.UnsignedInt.of_int 10 in 17 + assert (Jmap.Primitives.UnsignedInt.to_int limit = 10); 18 + 19 + (* Test comparator *) 20 + let sort = Jmap.Comparator.v ~property:"receivedAt" ~is_ascending:false () in 21 + assert (Jmap.Comparator.property sort = "receivedAt"); 22 + assert (not (Jmap.Comparator.is_ascending sort)); 23 + 24 + print_endline "✓ Unified Jmap module API works correctly"; 25 + print_endline " - Short aliases: Jmap.Id, Jmap.Capability, etc."; 26 + print_endline " - Mail modules: Jmap.Email, Jmap.Mailbox, etc."; 27 + print_endline " - Client API: Jmap.Client" 28 + 29 + let test_mail_module_aliases () = 30 + (* The unified module provides direct access to mail modules *) 31 + let account_id = Jmap.Id.of_string "test-account" in 32 + let limit = Jmap.Primitives.UnsignedInt.of_int 10 in 33 + 34 + let query_req = Jmap.Email.Query.request_v 35 + ~account_id 36 + ~limit 37 + ~calculate_total:true 38 + () 39 + in 40 + 41 + (* Verify it works *) 42 + let _json = Jmap.Email.Query.request_to_json query_req in 43 + 44 + print_endline "✓ Unified mail module aliases work"; 45 + print_endline " - Jmap.Email, Jmap.Mailbox, Jmap.Thread"; 46 + print_endline " - Clean and ergonomic" 47 + 48 + let test_submodule_aliases () = 49 + (* You can also use the submodules directly for specialized use *) 50 + let id1 = Jmap_core.Id.of_string "test123" in 51 + let id2 = Jmap_mail.Email.Query.request_v 52 + ~account_id:id1 53 + ~limit:(Jmap_core.Primitives.UnsignedInt.of_int 5) 54 + () 55 + in 56 + let _json = Jmap_mail.Email.Query.request_to_json id2 in 57 + 58 + print_endline "✓ Submodule access works"; 59 + print_endline " - Jmap_core.Id, Jmap_mail.Email"; 60 + print_endline " - For specialized use cases" 61 + 62 + let () = 63 + print_endline "=== Testing Unified Jmap API ===\n"; 64 + test_module_aliases (); 65 + print_endline ""; 66 + test_mail_module_aliases (); 67 + print_endline ""; 68 + test_submodule_aliases (); 69 + print_endline "\n✓ All tests passed!"