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