this repo has no description
1(**
2 * JMAP protocol implementation based on RFC8620
3 * https://datatracker.ietf.org/doc/html/rfc8620
4 *)
5
6(** Initialize and configure logging for JMAP *)
7val init_logging : ?level:int -> ?enable_logs:bool -> ?redact_sensitive:bool -> unit -> unit
8
9(** Redact sensitive data like tokens *)
10val redact_token : ?redact:bool -> string -> string
11
12(** Module for managing JMAP capability URIs and other constants *)
13module Capability : sig
14 (** JMAP capability URI as specified in RFC8620 *)
15 val core_uri : string
16
17 (** All JMAP capability types *)
18 type t =
19 | Core (** Core JMAP capability *)
20 | Extension of string (** Extension capabilities *)
21
22 (** Convert capability to URI string *)
23 val to_string : t -> string
24
25 (** Parse a string to a capability, returns Extension for non-core capabilities *)
26 val of_string : string -> t
27
28 (** Check if a capability matches a core capability *)
29 val is_core : t -> bool
30
31 (** Check if a capability string is a core capability *)
32 val is_core_string : string -> bool
33
34 (** Create a list of capability strings *)
35 val strings_of_capabilities : t list -> string list
36end
37
38(** {1 Types} *)
39
40module Types : sig
41 (** Id string as per Section 1.2 *)
42 type id = string
43
44 (** Int bounded within the range -2^53+1 to 2^53-1 as per Section 1.3 *)
45 type int_t = int
46
47 (** UnsignedInt bounded within the range 0 to 2^53-1 as per Section 1.3 *)
48 type unsigned_int = int
49
50 (** Date string in RFC3339 format as per Section 1.4 *)
51 type date = string
52
53 (** UTCDate is a Date with 'Z' time zone as per Section 1.4 *)
54 type utc_date = string
55
56 (** Error object as per Section 3.6.2 *)
57 type error = {
58 type_: string;
59 description: string option;
60 }
61
62 (** Set error object as per Section 5.3 *)
63 type set_error = {
64 type_: string;
65 description: string option;
66 properties: string list option;
67 (* Additional properties for specific error types *)
68 existing_id: id option; (* For alreadyExists error *)
69 }
70
71 (** Invocation object as per Section 3.2 *)
72 type 'a invocation = {
73 name: string;
74 arguments: 'a;
75 method_call_id: string;
76 }
77
78 (** ResultReference object as per Section 3.7 *)
79 type result_reference = {
80 result_of: string;
81 name: string;
82 path: string;
83 }
84
85 (** FilterOperator, FilterCondition and Filter as per Section 5.5 *)
86 type filter_operator = {
87 operator: string; (* "AND", "OR", "NOT" *)
88 conditions: filter list;
89 }
90 and filter_condition = (string * Ezjsonm.value) list
91 and filter =
92 | Operator of filter_operator
93 | Condition of filter_condition
94
95 (** Comparator object for sorting as per Section 5.5 *)
96 type comparator = {
97 property: string;
98 is_ascending: bool option; (* Optional, defaults to true *)
99 collation: string option; (* Optional, server-dependent default *)
100 }
101
102 (** PatchObject as per Section 5.3 *)
103 type patch_object = (string * Ezjsonm.value) list
104
105 (** AddedItem structure as per Section 5.6 *)
106 type added_item = {
107 id: id;
108 index: unsigned_int;
109 }
110
111 (** Account object as per Section 1.6.2 *)
112 type account = {
113 name: string;
114 is_personal: bool;
115 is_read_only: bool;
116 account_capabilities: (string * Ezjsonm.value) list;
117 }
118
119 (** Core capability object as per Section 2 *)
120 type core_capability = {
121 max_size_upload: unsigned_int;
122 max_concurrent_upload: unsigned_int;
123 max_size_request: unsigned_int;
124 max_concurrent_requests: unsigned_int;
125 max_calls_in_request: unsigned_int;
126 max_objects_in_get: unsigned_int;
127 max_objects_in_set: unsigned_int;
128 collation_algorithms: string list;
129 }
130
131 (** PushSubscription keys object as per Section 7.2 *)
132 type push_keys = {
133 p256dh: string;
134 auth: string;
135 }
136
137 (** Session object as per Section 2 *)
138 type session = {
139 capabilities: (string * Ezjsonm.value) list;
140 accounts: (id * account) list;
141 primary_accounts: (string * id) list;
142 username: string;
143 api_url: string;
144 download_url: string;
145 upload_url: string;
146 event_source_url: string option;
147 state: string;
148 }
149
150 (** TypeState for state changes as per Section 7.1 *)
151 type type_state = (string * string) list
152
153 (** StateChange object as per Section 7.1 *)
154 type state_change = {
155 changed: (id * type_state) list;
156 }
157
158 (** PushVerification object as per Section 7.2.2 *)
159 type push_verification = {
160 push_subscription_id: id;
161 verification_code: string;
162 }
163
164 (** PushSubscription object as per Section 7.2 *)
165 type push_subscription = {
166 id: id;
167 device_client_id: string;
168 url: string;
169 keys: push_keys option;
170 verification_code: string option;
171 expires: utc_date option;
172 types: string list option;
173 }
174
175 (** Request object as per Section 3.3 *)
176 type request = {
177 using: string list;
178 method_calls: Ezjsonm.value invocation list;
179 created_ids: (id * id) list option;
180 }
181
182 (** Response object as per Section 3.4 *)
183 type response = {
184 method_responses: Ezjsonm.value invocation list;
185 created_ids: (id * id) list option;
186 session_state: string;
187 }
188
189 (** Standard method arguments and responses *)
190
191 (** Arguments for Foo/get method as per Section 5.1 *)
192 type 'a get_arguments = {
193 account_id: id;
194 ids: id list option;
195 properties: string list option;
196 }
197
198 (** Response for Foo/get method as per Section 5.1 *)
199 type 'a get_response = {
200 account_id: id;
201 state: string;
202 list: 'a list;
203 not_found: id list;
204 }
205
206 (** Arguments for Foo/changes method as per Section 5.2 *)
207 type changes_arguments = {
208 account_id: id;
209 since_state: string;
210 max_changes: unsigned_int option;
211 }
212
213 (** Response for Foo/changes method as per Section 5.2 *)
214 type changes_response = {
215 account_id: id;
216 old_state: string;
217 new_state: string;
218 has_more_changes: bool;
219 created: id list;
220 updated: id list;
221 destroyed: id list;
222 }
223
224 (** Arguments for Foo/set method as per Section 5.3 *)
225 type 'a set_arguments = {
226 account_id: id;
227 if_in_state: string option;
228 create: (id * 'a) list option;
229 update: (id * patch_object) list option;
230 destroy: id list option;
231 }
232
233 (** Response for Foo/set method as per Section 5.3 *)
234 type 'a set_response = {
235 account_id: id;
236 old_state: string option;
237 new_state: string;
238 created: (id * 'a) list option;
239 updated: (id * 'a option) list option;
240 destroyed: id list option;
241 not_created: (id * set_error) list option;
242 not_updated: (id * set_error) list option;
243 not_destroyed: (id * set_error) list option;
244 }
245
246 (** Arguments for Foo/copy method as per Section 5.4 *)
247 type 'a copy_arguments = {
248 from_account_id: id;
249 if_from_in_state: string option;
250 account_id: id;
251 if_in_state: string option;
252 create: (id * 'a) list;
253 on_success_destroy_original: bool option;
254 destroy_from_if_in_state: string option;
255 }
256
257 (** Response for Foo/copy method as per Section 5.4 *)
258 type 'a copy_response = {
259 from_account_id: id;
260 account_id: id;
261 old_state: string option;
262 new_state: string;
263 created: (id * 'a) list option;
264 not_created: (id * set_error) list option;
265 }
266
267 (** Arguments for Foo/query method as per Section 5.5 *)
268 type query_arguments = {
269 account_id: id;
270 filter: filter option;
271 sort: comparator list option;
272 position: int_t option;
273 anchor: id option;
274 anchor_offset: int_t option;
275 limit: unsigned_int option;
276 calculate_total: bool option;
277 }
278
279 (** Response for Foo/query method as per Section 5.5 *)
280 type query_response = {
281 account_id: id;
282 query_state: string;
283 can_calculate_changes: bool;
284 position: unsigned_int;
285 ids: id list;
286 total: unsigned_int option;
287 limit: unsigned_int option;
288 }
289
290 (** Arguments for Foo/queryChanges method as per Section 5.6 *)
291 type query_changes_arguments = {
292 account_id: id;
293 filter: filter option;
294 sort: comparator list option;
295 since_query_state: string;
296 max_changes: unsigned_int option;
297 up_to_id: id option;
298 calculate_total: bool option;
299 }
300
301 (** Response for Foo/queryChanges method as per Section 5.6 *)
302 type query_changes_response = {
303 account_id: id;
304 old_query_state: string;
305 new_query_state: string;
306 total: unsigned_int option;
307 removed: id list;
308 added: added_item list option;
309 }
310
311 (** Arguments for Blob/copy method as per Section 6.3 *)
312 type blob_copy_arguments = {
313 from_account_id: id;
314 account_id: id;
315 blob_ids: id list;
316 }
317
318 (** Response for Blob/copy method as per Section 6.3 *)
319 type blob_copy_response = {
320 from_account_id: id;
321 account_id: id;
322 copied: (id * id) list option;
323 not_copied: (id * set_error) list option;
324 }
325
326 (** Upload response as per Section 6.1 *)
327 type upload_response = {
328 account_id: id;
329 blob_id: id;
330 type_: string;
331 size: unsigned_int;
332 }
333
334 (** Problem details object as per RFC7807 and Section 3.6.1 *)
335 type problem_details = {
336 type_: string;
337 status: int option;
338 detail: string option;
339 limit: string option; (* For "limit" error *)
340 }
341end
342
343(** {1 API Client} *)
344
345(** Module for making JMAP API requests over HTTP.
346 Provides functionality to interact with JMAP servers according to RFC8620. *)
347module Api : sig
348 (** Error that may occur during API requests *)
349 type error =
350 | Connection_error of string
351 | HTTP_error of int * string
352 | Parse_error of string
353 | Authentication_error
354
355 (** Result type for API operations *)
356 type 'a result = ('a, error) Stdlib.result
357
358 (** Configuration for a JMAP API client *)
359 type config = {
360 api_uri: Uri.t;
361 username: string;
362 authentication_token: string;
363 }
364
365 (** Make a raw JMAP API request *)
366 val make_request :
367 config ->
368 Types.request ->
369 Types.response result Lwt.t
370
371 (** Fetch a Session object from a JMAP server.
372 Can authenticate with either username/password or API token. *)
373 val get_session :
374 Uri.t ->
375 ?username:string ->
376 ?authentication_token:string ->
377 ?api_token:string ->
378 unit ->
379 Types.session result Lwt.t
380
381 (** Upload a binary blob to the server *)
382 val upload_blob :
383 config ->
384 account_id:Types.id ->
385 content_type:string ->
386 string ->
387 Types.upload_response result Lwt.t
388
389 (** Download a binary blob from the server *)
390 val download_blob :
391 config ->
392 account_id:Types.id ->
393 blob_id:Types.id ->
394 ?type_:string ->
395 ?name:string ->
396 unit ->
397 string result Lwt.t
398end