this repo has no description
1(* Standard JMAP Methods and Core/echo. *) 2 3open Jmap_types 4open Jmap_error 5 6(* Generic representation of a record type. Actual types defined elsewhere. *) 7type generic_record = Yojson.Safe.t 8 9(* Arguments for /get methods. *) 10module Get_args = struct 11 type 'record t = { 12 account_id: id; 13 ids: id list option; 14 properties: string list option; 15 } 16 17 let account_id t = t.account_id 18 let ids t = t.ids 19 let properties t = t.properties 20 21 let v ~account_id ?ids ?properties () = 22 { account_id; ids; properties } 23end 24 25(* Response for /get methods. *) 26module Get_response = struct 27 type 'record t = { 28 account_id: id; 29 state: string; 30 list: 'record list; 31 not_found: id list; 32 } 33 34 let account_id t = t.account_id 35 let state t = t.state 36 let list t = t.list 37 let not_found t = t.not_found 38 39 let v ~account_id ~state ~list ~not_found () = 40 { account_id; state; list; not_found } 41end 42 43(* Arguments for /changes methods. *) 44module Changes_args = struct 45 type t = { 46 account_id: id; 47 since_state: string; 48 max_changes: uint option; 49 } 50 51 let account_id t = t.account_id 52 let since_state t = t.since_state 53 let max_changes t = t.max_changes 54 55 let v ~account_id ~since_state ?max_changes () = 56 { account_id; since_state; max_changes } 57end 58 59(* Response for /changes methods. *) 60module Changes_response = struct 61 type t = { 62 account_id: id; 63 old_state: string; 64 new_state: string; 65 has_more_changes: bool; 66 created: id list; 67 updated: id list; 68 destroyed: id list; 69 updated_properties: string list option; 70 } 71 72 let account_id t = t.account_id 73 let old_state t = t.old_state 74 let new_state t = t.new_state 75 let has_more_changes t = t.has_more_changes 76 let created t = t.created 77 let updated t = t.updated 78 let destroyed t = t.destroyed 79 let updated_properties t = t.updated_properties 80 81 let v ~account_id ~old_state ~new_state ~has_more_changes 82 ~created ~updated ~destroyed ?updated_properties () = 83 { account_id; old_state; new_state; has_more_changes; 84 created; updated; destroyed; updated_properties } 85end 86 87(* Patch object for /set update. 88 A list of (JSON Pointer path, value) pairs. *) 89type patch_object = (json_pointer * Yojson.Safe.t) list 90 91(* Arguments for /set methods. *) 92module Set_args = struct 93 type ('create_record, 'update_record) t = { 94 account_id: id; 95 if_in_state: string option; 96 create: 'create_record id_map option; 97 update: 'update_record id_map option; 98 destroy: id list option; 99 on_success_destroy_original: bool option; 100 destroy_from_if_in_state: string option; 101 on_destroy_remove_emails: bool option; 102 } 103 104 let account_id t = t.account_id 105 let if_in_state t = t.if_in_state 106 let create t = t.create 107 let update t = t.update 108 let destroy t = t.destroy 109 let on_success_destroy_original t = t.on_success_destroy_original 110 let destroy_from_if_in_state t = t.destroy_from_if_in_state 111 let on_destroy_remove_emails t = t.on_destroy_remove_emails 112 113 let v ~account_id ?if_in_state ?create ?update ?destroy 114 ?on_success_destroy_original ?destroy_from_if_in_state 115 ?on_destroy_remove_emails () = 116 { account_id; if_in_state; create; update; destroy; 117 on_success_destroy_original; destroy_from_if_in_state; 118 on_destroy_remove_emails } 119end 120 121(* Response for /set methods. *) 122module Set_response = struct 123 type ('created_record_info, 'updated_record_info) t = { 124 account_id: id; 125 old_state: string option; 126 new_state: string; 127 created: 'created_record_info id_map option; 128 updated: 'updated_record_info option id_map option; 129 destroyed: id list option; 130 not_created: Set_error.t id_map option; 131 not_updated: Set_error.t id_map option; 132 not_destroyed: Set_error.t id_map option; 133 } 134 135 let account_id t = t.account_id 136 let old_state t = t.old_state 137 let new_state t = t.new_state 138 let created t = t.created 139 let updated t = t.updated 140 let destroyed t = t.destroyed 141 let not_created t = t.not_created 142 let not_updated t = t.not_updated 143 let not_destroyed t = t.not_destroyed 144 145 let v ~account_id ?old_state ~new_state ?created ?updated ?destroyed 146 ?not_created ?not_updated ?not_destroyed () = 147 { account_id; old_state; new_state; created; updated; destroyed; 148 not_created; not_updated; not_destroyed } 149end 150 151(* Arguments for /copy methods. *) 152module Copy_args = struct 153 type 'copy_record_override t = { 154 from_account_id: id; 155 if_from_in_state: string option; 156 account_id: id; 157 if_in_state: string option; 158 create: 'copy_record_override id_map; 159 on_success_destroy_original: bool; 160 destroy_from_if_in_state: string option; 161 } 162 163 let from_account_id t = t.from_account_id 164 let if_from_in_state t = t.if_from_in_state 165 let account_id t = t.account_id 166 let if_in_state t = t.if_in_state 167 let create t = t.create 168 let on_success_destroy_original t = t.on_success_destroy_original 169 let destroy_from_if_in_state t = t.destroy_from_if_in_state 170 171 let v ~from_account_id ?if_from_in_state ~account_id ?if_in_state 172 ~create ?(on_success_destroy_original=false) ?destroy_from_if_in_state () = 173 { from_account_id; if_from_in_state; account_id; if_in_state; 174 create; on_success_destroy_original; destroy_from_if_in_state } 175end 176 177(* Response for /copy methods. *) 178module Copy_response = struct 179 type 'created_record_info t = { 180 from_account_id: id; 181 account_id: id; 182 old_state: string option; 183 new_state: string; 184 created: 'created_record_info id_map option; 185 not_created: Set_error.t id_map option; 186 } 187 188 let from_account_id t = t.from_account_id 189 let account_id t = t.account_id 190 let old_state t = t.old_state 191 let new_state t = t.new_state 192 let created t = t.created 193 let not_created t = t.not_created 194 195 let v ~from_account_id ~account_id ?old_state ~new_state 196 ?created ?not_created () = 197 { from_account_id; account_id; old_state; new_state; 198 created; not_created } 199end 200 201(* Module for generic filter representation. *) 202module Filter = struct 203 type t = 204 | Condition of Yojson.Safe.t 205 | Operator of [ `AND | `OR | `NOT ] * t list 206 207 let condition json = Condition json 208 209 let operator op filters = Operator (op, filters) 210 211 let and_ filters = operator `AND filters 212 213 let or_ filters = operator `OR filters 214 215 let not_ filter = operator `NOT [filter] 216 217 let rec to_json = function 218 | Condition json -> json 219 | Operator (op, filters) -> 220 let key = match op with 221 | `AND -> "AND" 222 | `OR -> "OR" 223 | `NOT -> "NOT" 224 in 225 `Assoc [(key, `List (List.map to_json filters))] 226 227 (* Helper functions for common filter conditions *) 228 229 let text_contains property value = 230 condition (`Assoc [ 231 (property, `Assoc [("contains", `String value)]) 232 ]) 233 234 let property_equals property value = 235 condition (`Assoc [(property, value)]) 236 237 let property_not_equals property value = 238 condition (`Assoc [ 239 (property, `Assoc [("!",value)]) 240 ]) 241 242 let property_gt property value = 243 condition (`Assoc [ 244 (property, `Assoc [("gt", value)]) 245 ]) 246 247 let property_ge property value = 248 condition (`Assoc [ 249 (property, `Assoc [("ge", value)]) 250 ]) 251 252 let property_lt property value = 253 condition (`Assoc [ 254 (property, `Assoc [("lt", value)]) 255 ]) 256 257 let property_le property value = 258 condition (`Assoc [ 259 (property, `Assoc [("le", value)]) 260 ]) 261 262 let property_in property values = 263 condition (`Assoc [ 264 (property, `Assoc [("in", `List values)]) 265 ]) 266 267 let property_not_in property values = 268 condition (`Assoc [ 269 (property, `Assoc [("!in", `List values)]) 270 ]) 271 272 let property_exists property = 273 condition (`Assoc [ 274 (property, `Null) (* Using just the property name means "property exists" *) 275 ]) 276 277 let string_starts_with property prefix = 278 condition (`Assoc [ 279 (property, `Assoc [("startsWith", `String prefix)]) 280 ]) 281 282 let string_ends_with property suffix = 283 condition (`Assoc [ 284 (property, `Assoc [("endsWith", `String suffix)]) 285 ]) 286end 287 288(* Comparator for sorting. *) 289module Comparator = struct 290 type t = { 291 property: string; 292 is_ascending: bool option; 293 collation: string option; 294 keyword: string option; 295 other_fields: Yojson.Safe.t string_map; 296 } 297 298 let property t = t.property 299 let is_ascending t = t.is_ascending 300 let collation t = t.collation 301 let keyword t = t.keyword 302 let other_fields t = t.other_fields 303 304 let v ~property ?is_ascending ?collation ?keyword 305 ?(other_fields=Hashtbl.create 0) () = 306 { property; is_ascending; collation; keyword; other_fields } 307end 308 309(* Arguments for /query methods. *) 310module Query_args = struct 311 type t = { 312 account_id: id; 313 filter: Filter.t option; 314 sort: Comparator.t list option; 315 position: jint option; 316 anchor: id option; 317 anchor_offset: jint option; 318 limit: uint option; 319 calculate_total: bool option; 320 collapse_threads: bool option; 321 sort_as_tree: bool option; 322 filter_as_tree: bool option; 323 } 324 325 let account_id t = t.account_id 326 let filter t = t.filter 327 let sort t = t.sort 328 let position t = t.position 329 let anchor t = t.anchor 330 let anchor_offset t = t.anchor_offset 331 let limit t = t.limit 332 let calculate_total t = t.calculate_total 333 let collapse_threads t = t.collapse_threads 334 let sort_as_tree t = t.sort_as_tree 335 let filter_as_tree t = t.filter_as_tree 336 337 let v ~account_id ?filter ?sort ?position ?anchor ?anchor_offset 338 ?limit ?calculate_total ?collapse_threads ?sort_as_tree ?filter_as_tree () = 339 { account_id; filter; sort; position; anchor; anchor_offset; 340 limit; calculate_total; collapse_threads; sort_as_tree; filter_as_tree } 341end 342 343(* Response for /query methods. *) 344module Query_response = struct 345 type t = { 346 account_id: id; 347 query_state: string; 348 can_calculate_changes: bool; 349 position: uint; 350 ids: id list; 351 total: uint option; 352 limit: uint option; 353 } 354 355 let account_id t = t.account_id 356 let query_state t = t.query_state 357 let can_calculate_changes t = t.can_calculate_changes 358 let position t = t.position 359 let ids t = t.ids 360 let total t = t.total 361 let limit t = t.limit 362 363 let v ~account_id ~query_state ~can_calculate_changes ~position ~ids 364 ?total ?limit () = 365 { account_id; query_state; can_calculate_changes; position; ids; 366 total; limit } 367end 368 369(* Item indicating an added record in /queryChanges. *) 370module Added_item = struct 371 type t = { 372 id: id; 373 index: uint; 374 } 375 376 let id t = t.id 377 let index t = t.index 378 379 let v ~id ~index () = { id; index } 380end 381 382(* Arguments for /queryChanges methods. *) 383module Query_changes_args = struct 384 type t = { 385 account_id: id; 386 filter: Filter.t option; 387 sort: Comparator.t list option; 388 since_query_state: string; 389 max_changes: uint option; 390 up_to_id: id option; 391 calculate_total: bool option; 392 collapse_threads: bool option; 393 } 394 395 let account_id t = t.account_id 396 let filter t = t.filter 397 let sort t = t.sort 398 let since_query_state t = t.since_query_state 399 let max_changes t = t.max_changes 400 let up_to_id t = t.up_to_id 401 let calculate_total t = t.calculate_total 402 let collapse_threads t = t.collapse_threads 403 404 let v ~account_id ?filter ?sort ~since_query_state ?max_changes 405 ?up_to_id ?calculate_total ?collapse_threads () = 406 { account_id; filter; sort; since_query_state; max_changes; 407 up_to_id; calculate_total; collapse_threads } 408end 409 410(* Response for /queryChanges methods. *) 411module Query_changes_response = struct 412 type t = { 413 account_id: id; 414 old_query_state: string; 415 new_query_state: string; 416 total: uint option; 417 removed: id list; 418 added: Added_item.t list; 419 } 420 421 let account_id t = t.account_id 422 let old_query_state t = t.old_query_state 423 let new_query_state t = t.new_query_state 424 let total t = t.total 425 let removed t = t.removed 426 let added t = t.added 427 428 let v ~account_id ~old_query_state ~new_query_state ?total 429 ~removed ~added () = 430 { account_id; old_query_state; new_query_state; total; 431 removed; added } 432end 433 434(* Core/echo method: Arguments are mirrored in the response. *) 435type core_echo_args = Yojson.Safe.t 436type core_echo_response = Yojson.Safe.t