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