Google Docs API client for OCaml
0
fork

Configure Feed

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

json: rename mem -> member / finish -> seal across the codec + value API

Object combinators: [Object.mem] -> [Object.member], [Object.opt_mem]
-> [Object.opt_member], [Object.case_mem] -> [Object.case_member]. The
sibling submodules [Object.Mem] / [Object.Mems] become
[Object.Member] / [Object.Members]. RFC 8259 §4 calls these
"name/value pairs, referred to as the members", so mirror the spec
name rather than the shortened [mem].

[Object.finish] -> [Object.seal]. "Seal" reads as "close the map, no
more members added", which is what the operation does.

Value constructors/queries: [Value.mem] (function) -> [Value.member];
[Value.mem_find] -> [Value.member_key]; [Value.mem_names] ->
[Value.member_names]; [Value.mem_keys] -> [Value.member_keys].
[type mem = ...] -> [type member = ...]; [type object'] still points
at [member list].

Downstream (~80 files across slack, sbom, stripe, sigstore, requests,
claude, irmin, freebox) updated via perl-pie. dune build clean,
dune test ocaml-json clean.

+21 -21
+2 -2
dune-project
··· 28 28 (gauth (>= 0.1)) 29 29 (http (>= 0.1)) 30 30 (json (>= 0.2)) 31 - (bytesrw (>= 0.1)) 32 31 (logs (>= 0.7)) 33 32 (oauth (>= 0.1)) 34 33 (requests (>= 0.1)) 35 34 (xdge (>= 0.1)) 36 35 (alcotest :with-test) 37 36 (crypto-rng :with-test) 38 - (odoc :with-doc))) 37 + (odoc :with-doc) 38 + uri))
+1 -1
gdocs.opam
··· 22 22 "gauth" {>= "0.1"} 23 23 "http" {>= "0.1"} 24 24 "json" {>= "0.2"} 25 - "bytesrw" {>= "0.1"} 26 25 "logs" {>= "0.7"} 27 26 "oauth" {>= "0.1"} 28 27 "requests" {>= "0.1"} ··· 30 29 "alcotest" {with-test} 31 30 "crypto-rng" {with-test} 32 31 "odoc" {with-doc} 32 + "uri" 33 33 ] 34 34 build: [ 35 35 ["dune" "subst"] {dev}
+13 -13
lib/comments.ml
··· 44 44 let author_jsont = 45 45 let open Json.Codec in 46 46 Object.map ~kind:"author" (fun display_name -> { display_name }) 47 - |> Object.mem "displayName" string ~dec_absent:"" ~enc:(fun a -> 47 + |> Object.member "displayName" string ~dec_absent:"" ~enc:(fun a -> 48 48 a.display_name) 49 - |> Object.skip_unknown |> Object.finish 49 + |> Object.skip_unknown |> Object.seal 50 50 51 51 type raw_quoted = { value : string } 52 52 53 53 let quoted_jsont = 54 54 let open Json.Codec in 55 55 Object.map ~kind:"quotedFileContent" (fun value -> { value }) 56 - |> Object.mem "value" string ~dec_absent:"" ~enc:(fun q -> q.value) 57 - |> Object.skip_unknown |> Object.finish 56 + |> Object.member "value" string ~dec_absent:"" ~enc:(fun q -> q.value) 57 + |> Object.skip_unknown |> Object.seal 58 58 59 59 let comment_jsont = 60 60 let open Json.Codec in ··· 67 67 anchor; 68 68 resolved; 69 69 }) 70 - |> Object.mem "id" string ~enc:id 71 - |> Object.opt_mem "author" author_jsont ~enc:(fun _ -> None) 72 - |> Object.mem "content" string ~dec_absent:"" ~enc:(fun c -> c.content) 73 - |> Object.opt_mem "quotedFileContent" quoted_jsont ~enc:(fun _ -> None) 74 - |> Object.opt_mem "anchor" string ~enc:(fun c -> c.anchor) 75 - |> Object.mem "resolved" bool ~dec_absent:false ~enc:(fun c -> c.resolved) 76 - |> Object.skip_unknown |> Object.finish 70 + |> Object.member "id" string ~enc:id 71 + |> Object.opt_member "author" author_jsont ~enc:(fun _ -> None) 72 + |> Object.member "content" string ~dec_absent:"" ~enc:(fun c -> c.content) 73 + |> Object.opt_member "quotedFileContent" quoted_jsont ~enc:(fun _ -> None) 74 + |> Object.opt_member "anchor" string ~enc:(fun c -> c.anchor) 75 + |> Object.member "resolved" bool ~dec_absent:false ~enc:(fun c -> c.resolved) 76 + |> Object.skip_unknown |> Object.seal 77 77 78 78 type raw_list = { comments : t list } 79 79 80 80 let list_jsont = 81 81 let open Json.Codec in 82 82 Object.map ~kind:"comment_list" (fun comments -> { comments }) 83 - |> Object.mem "comments" (list comment_jsont) ~dec_absent:[] ~enc:(fun r -> 83 + |> Object.member "comments" (list comment_jsont) ~dec_absent:[] ~enc:(fun r -> 84 84 r.comments) 85 - |> Object.skip_unknown |> Object.finish 85 + |> Object.skip_unknown |> Object.seal 86 86 87 87 let of_json_string body = 88 88 match Json.of_string list_jsont body with
+1 -1
lib/document.ml
··· 8 8 let id d = d.document_id 9 9 let title d = d.title 10 10 let to_json d = d.raw 11 - let mem_name ((n, _) : Json.name) = n 11 + let mem_name ((n, _) : Json.Value.name) = n 12 12 13 13 (* Walk the document JSON and extract plain text. 14 14
+1 -1
lib/markdown.ml
··· 6 6 we only generate. Tests round-trip the output through 7 7 Cmarkit.Doc.of_string to confirm it parses cleanly. *) 8 8 9 - let mem_name ((n, _) : Json.name) = n 9 + let mem_name ((n, _) : Json.Value.name) = n 10 10 11 11 (* Find a named member on an Object node. *) 12 12 let member json field =
+3 -3
lib/store.ml
··· 15 15 let open Json.Codec in 16 16 Object.map ~kind:"gdocs_client" (fun client_id client_secret -> 17 17 { client_id; client_secret }) 18 - |> Object.mem "client_id" string ~enc:(fun c -> c.client_id) 19 - |> Object.mem "client_secret" string ~enc:(fun c -> c.client_secret) 20 - |> Object.skip_unknown |> Object.finish 18 + |> Object.member "client_id" string ~enc:(fun c -> c.client_id) 19 + |> Object.member "client_secret" string ~enc:(fun c -> c.client_secret) 20 + |> Object.skip_unknown |> Object.seal 21 21 22 22 let save_file path data = 23 23 Eio.Path.save ~create:(`Or_truncate 0o600) path data;