Stripe 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.

+59 -55
+2 -2
dune-project
··· 20 20 ocaml-requests for HTTP and jsont for JSON codec.") 21 21 (depends 22 22 (ocaml (>= 4.14)) 23 - bytesrw 24 23 fmt 25 24 (requests (>= 0.1)) 26 25 (json (>= 0.1)) 27 26 (digestif (>= 1.0)) 28 - (alcotest :with-test))) 27 + (alcotest :with-test) 28 + loc))
+56 -52
lib/stripe.ml
··· 30 30 let open Json.Codec in 31 31 Object.map (fun error_type message code -> 32 32 { error_type; message; code; status = 0 }) 33 - |> Object.mem "type" string ~dec_absent:"" ~enc:(fun e -> e.error_type) 34 - |> Object.mem "message" string ~dec_absent:"" ~enc:(fun e -> e.message) 35 - |> Object.mem "code" string ~dec_absent:"" ~enc:(fun e -> e.code) 36 - |> Object.finish 33 + |> Object.member "type" string ~dec_absent:"" ~enc:(fun e -> e.error_type) 34 + |> Object.member "message" string ~dec_absent:"" ~enc:(fun e -> e.message) 35 + |> Object.member "code" string ~dec_absent:"" ~enc:(fun e -> e.code) 36 + |> Object.seal 37 37 38 38 let error_wrapper_jsont = 39 39 let open Json.Codec in 40 40 Object.map Fun.id 41 - |> Object.mem "error" error_jsont ~enc:Fun.id 42 - |> Object.finish 41 + |> Object.member "error" error_jsont ~enc:Fun.id 42 + |> Object.seal 43 43 44 44 (* {1 Common types} *) 45 45 ··· 84 84 let list_jsont item_jsont = 85 85 let open Json.Codec in 86 86 Object.map (fun data has_more -> (data, has_more)) 87 - |> Object.mem "data" (list item_jsont) ~enc:(fun (d, _) -> d) 88 - |> Object.mem "has_more" bool ~enc:(fun (_, h) -> h) 89 - |> Object.finish 87 + |> Object.member "data" (list item_jsont) ~enc:(fun (d, _) -> d) 88 + |> Object.member "has_more" bool ~enc:(fun (_, h) -> h) 89 + |> Object.seal 90 90 91 91 (* {1 Customers} *) 92 92 ··· 110 110 let open Json.Codec in 111 111 Object.map (fun id email name metadata created -> 112 112 { id; email; name; metadata; created }) 113 - |> Object.mem "id" string ~enc:id 114 - |> Object.mem "email" string ~dec_absent:"" ~enc:email 115 - |> Object.mem "name" string ~dec_absent:"" ~enc:name 116 - |> Object.mem "metadata" metadata_jsont ~dec_absent:Smap.empty ~enc:metadata 117 - |> Object.mem "created" int ~dec_absent:0 ~enc:created 118 - |> Object.finish 113 + |> Object.member "id" string ~enc:id 114 + |> Object.member "email" string ~dec_absent:"" ~enc:email 115 + |> Object.member "name" string ~dec_absent:"" ~enc:name 116 + |> Object.member "metadata" metadata_jsont ~dec_absent:Smap.empty 117 + ~enc:metadata 118 + |> Object.member "created" int ~dec_absent:0 ~enc:created 119 + |> Object.seal 119 120 120 121 let create cfg ~email ?name ?metadata () = 121 122 let body = ··· 156 157 let jsont = 157 158 let open Json.Codec in 158 159 Object.map (fun id name active metadata -> { id; name; active; metadata }) 159 - |> Object.mem "id" string ~enc:id 160 - |> Object.mem "name" string ~enc:name 161 - |> Object.mem "active" bool ~dec_absent:true ~enc:active 162 - |> Object.mem "metadata" metadata_jsont ~dec_absent:Smap.empty ~enc:metadata 163 - |> Object.finish 160 + |> Object.member "id" string ~enc:id 161 + |> Object.member "name" string ~enc:name 162 + |> Object.member "active" bool ~dec_absent:true ~enc:active 163 + |> Object.member "metadata" metadata_jsont ~dec_absent:Smap.empty 164 + ~enc:metadata 165 + |> Object.seal 164 166 165 167 let create cfg ~name ?metadata () = 166 168 let body = ··· 184 186 let recurring_jsont = 185 187 let open Json.Codec in 186 188 Object.map (fun interval interval_count -> { interval; interval_count }) 187 - |> Object.mem "interval" string ~enc:(fun r -> r.interval) 188 - |> Object.mem "interval_count" int ~dec_absent:1 ~enc:(fun r -> 189 + |> Object.member "interval" string ~enc:(fun r -> r.interval) 190 + |> Object.member "interval_count" int ~dec_absent:1 ~enc:(fun r -> 189 191 r.interval_count) 190 - |> Object.finish 192 + |> Object.seal 191 193 192 194 type t = { 193 195 id : string; ··· 210 212 let open Json.Codec in 211 213 Object.map (fun id product unit_amount currency recurring active -> 212 214 { id; product; unit_amount; currency; recurring; active }) 213 - |> Object.mem "id" string ~enc:id 214 - |> Object.mem "product" string ~enc:product 215 - |> Object.mem "unit_amount" int ~dec_absent:0 ~enc:unit_amount 216 - |> Object.mem "currency" string ~enc:currency 217 - |> Object.mem "recurring" (option recurring_jsont) ~dec_absent:None 215 + |> Object.member "id" string ~enc:id 216 + |> Object.member "product" string ~enc:product 217 + |> Object.member "unit_amount" int ~dec_absent:0 ~enc:unit_amount 218 + |> Object.member "currency" string ~enc:currency 219 + |> Object.member "recurring" (option recurring_jsont) ~dec_absent:None 218 220 ~enc:recurring 219 - |> Object.mem "active" bool ~dec_absent:true ~enc:active 220 - |> Object.finish 221 + |> Object.member "active" bool ~dec_absent:true ~enc:active 222 + |> Object.seal 221 223 222 224 let create cfg ~product ~unit_amount ~currency ?interval ?interval_count () = 223 225 let body = ··· 282 284 cancel_at_period_end; 283 285 metadata; 284 286 }) 285 - |> Object.mem "id" string ~enc:id 286 - |> Object.mem "customer" string ~enc:customer 287 - |> Object.mem "status" string ~enc:status 288 - |> Object.mem "current_period_start" int ~dec_absent:0 287 + |> Object.member "id" string ~enc:id 288 + |> Object.member "customer" string ~enc:customer 289 + |> Object.member "status" string ~enc:status 290 + |> Object.member "current_period_start" int ~dec_absent:0 289 291 ~enc:current_period_start 290 - |> Object.mem "current_period_end" int ~dec_absent:0 ~enc:current_period_end 291 - |> Object.mem "cancel_at_period_end" bool ~dec_absent:false 292 + |> Object.member "current_period_end" int ~dec_absent:0 293 + ~enc:current_period_end 294 + |> Object.member "cancel_at_period_end" bool ~dec_absent:false 292 295 ~enc:cancel_at_period_end 293 - |> Object.mem "metadata" metadata_jsont ~dec_absent:Smap.empty ~enc:metadata 294 - |> Object.finish 296 + |> Object.member "metadata" metadata_jsont ~dec_absent:Smap.empty 297 + ~enc:metadata 298 + |> Object.seal 295 299 296 300 let create cfg ~customer ~price ?metadata () = 297 301 let body = ··· 333 337 let open Json.Codec in 334 338 Object.map (fun id url customer subscription status -> 335 339 { id; url; customer; subscription; status }) 336 - |> Object.mem "id" string ~enc:id 337 - |> Object.mem "url" string ~dec_absent:"" ~enc:url 338 - |> Object.mem "customer" string ~dec_absent:"" ~enc:customer 339 - |> Object.mem "subscription" string ~dec_absent:"" ~enc:subscription 340 - |> Object.mem "status" string ~dec_absent:"" ~enc:status 341 - |> Object.finish 340 + |> Object.member "id" string ~enc:id 341 + |> Object.member "url" string ~dec_absent:"" ~enc:url 342 + |> Object.member "customer" string ~dec_absent:"" ~enc:customer 343 + |> Object.member "subscription" string ~dec_absent:"" ~enc:subscription 344 + |> Object.member "status" string ~dec_absent:"" ~enc:status 345 + |> Object.seal 342 346 343 347 let create cfg ?customer ?customer_email ~price ~success_url ~cancel_url () = 344 348 let body = ··· 372 376 let jsont = 373 377 let open Json.Codec in 374 378 Object.map (fun id url -> { id; url }) 375 - |> Object.mem "id" string ~enc:id 376 - |> Object.mem "url" string ~enc:url 377 - |> Object.finish 379 + |> Object.member "id" string ~enc:id 380 + |> Object.member "url" string ~enc:url 381 + |> Object.seal 378 382 379 383 let create cfg ~customer ~return_url = 380 384 let body = [ ("customer", customer); ("return_url", return_url) ] in ··· 401 405 let open Json.Codec in 402 406 Object.map (fun id event_type created data -> 403 407 { id; event_type; created; data }) 404 - |> Object.mem "id" string ~enc:event_id 405 - |> Object.mem "type" string ~enc:event_type 406 - |> Object.mem "created" int ~dec_absent:0 ~enc:event_created 407 - |> Object.mem "data" Value.t ~enc:event_data 408 - |> Object.finish 408 + |> Object.member "id" string ~enc:event_id 409 + |> Object.member "type" string ~enc:event_type 410 + |> Object.member "created" int ~dec_absent:0 ~enc:event_created 411 + |> Object.member "data" Value.t ~enc:event_data 412 + |> Object.seal 409 413 410 414 (* Stripe webhook signature verification. 411 415 Header format: t=<timestamp>,v1=<sig1>,v1=<sig2>,...
+1 -1
stripe.opam
··· 12 12 depends: [ 13 13 "dune" {>= "3.21"} 14 14 "ocaml" {>= "4.14"} 15 - "bytesrw" 16 15 "fmt" 17 16 "requests" {>= "0.1"} 18 17 "json" {>= "0.1"} 19 18 "digestif" {>= "1.0"} 20 19 "alcotest" {with-test} 20 + "loc" 21 21 "odoc" {with-doc} 22 22 ] 23 23 build: [