OSV.dev vulnerability database client
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.

+48 -60
+2 -2
dune-project
··· 26 26 (logs (>= 0.7)) 27 27 (astring (>= 0.8)) 28 28 (json (>= 0.1)) 29 - (bytesrw (>= 0.1)) 30 - (alcotest :with-test))) 29 + (alcotest :with-test) 30 + loc))
+45 -57
lib/osv.ml
··· 56 56 57 57 let severity_entry_jsont : severity_entry Json.codec = 58 58 let open Json.Codec in 59 - Object.map ~kind:"severity_entry" (fun sev_type score -> 60 - { sev_type; score }) 61 - |> Object.mem "type" string ~dec_absent:"" 62 - ~enc:(fun s -> s.sev_type) 63 - |> Object.mem "score" string ~dec_absent:"" 64 - ~enc:(fun s -> s.score) 65 - |> Object.skip_unknown |> Object.finish 59 + Object.map ~kind:"severity_entry" (fun sev_type score -> { sev_type; score }) 60 + |> Object.member "type" string ~dec_absent:"" ~enc:(fun s -> s.sev_type) 61 + |> Object.member "score" string ~dec_absent:"" ~enc:(fun s -> s.score) 62 + |> Object.skip_unknown |> Object.seal 66 63 67 64 (* Reference: {"type": "WEB", "url": "https://..."} *) 68 65 let reference_jsont : reference Json.codec = 69 66 let open Json.Codec in 70 - Object.map ~kind:"reference" (fun ref_type url -> 71 - { ref_type; url }) 72 - |> Object.mem "type" string ~dec_absent:"" 73 - ~enc:(fun r -> r.ref_type) 74 - |> Object.mem "url" string ~dec_absent:"" ~enc:(fun r -> 75 - r.url) 76 - |> Object.skip_unknown |> Object.finish 67 + Object.map ~kind:"reference" (fun ref_type url -> { ref_type; url }) 68 + |> Object.member "type" string ~dec_absent:"" ~enc:(fun r -> r.ref_type) 69 + |> Object.member "url" string ~dec_absent:"" ~enc:(fun r -> r.url) 70 + |> Object.skip_unknown |> Object.seal 77 71 78 72 (* Event: {"introduced": "0", "fixed": "1.2.3"} *) 79 73 type range_event = { event_type : string; event_version : string } ··· 83 77 (* Events are objects with a single key being the event type *) 84 78 Object.map ~kind:"range_event" (fun event_type event_version -> 85 79 { event_type; event_version }) 86 - |> Object.mem "introduced" string ~dec_absent:"" 87 - ~enc:(fun e -> e.event_type) 88 - |> Object.mem "fixed" string ~dec_absent:"" 89 - ~enc:(fun e -> e.event_version) 90 - |> Object.skip_unknown |> Object.finish 80 + |> Object.member "introduced" string ~dec_absent:"" ~enc:(fun e -> 81 + e.event_type) 82 + |> Object.member "fixed" string ~dec_absent:"" ~enc:(fun e -> e.event_version) 83 + |> Object.skip_unknown |> Object.seal 91 84 92 85 (* Range: {"type": "SEMVER", "events": [...]} *) 93 86 type raw_range = { rr_type : string; events : range_event list } 94 87 95 88 let raw_range_jsont : raw_range Json.codec = 96 89 let open Json.Codec in 97 - Object.map ~kind:"range" (fun rr_type events -> 98 - { rr_type; events }) 99 - |> Object.mem "type" string ~dec_absent:"" 100 - ~enc:(fun r -> r.rr_type) 101 - |> Object.mem "events" (list range_event_jsont) 102 - ~dec_absent:[] ~enc:(fun r -> r.events) 103 - |> Object.skip_unknown |> Object.finish 90 + Object.map ~kind:"range" (fun rr_type events -> { rr_type; events }) 91 + |> Object.member "type" string ~dec_absent:"" ~enc:(fun r -> r.rr_type) 92 + |> Object.member "events" (list range_event_jsont) ~dec_absent:[] 93 + ~enc:(fun r -> r.events) 94 + |> Object.skip_unknown |> Object.seal 104 95 105 96 (* Affected: {"ranges": [...]} *) 106 97 type raw_affected = { ranges : raw_range list } ··· 108 99 let raw_affected_jsont : raw_affected Json.codec = 109 100 let open Json.Codec in 110 101 Object.map ~kind:"affected" (fun ranges -> { ranges }) 111 - |> Object.mem "ranges" (list raw_range_jsont) 112 - ~dec_absent:[] ~enc:(fun a -> a.ranges) 113 - |> Object.skip_unknown |> Object.finish 102 + |> Object.member "ranges" (list raw_range_jsont) ~dec_absent:[] ~enc:(fun a -> 103 + a.ranges) 104 + |> Object.skip_unknown |> Object.seal 114 105 115 106 (* Vulnerability (top-level OSV record) *) 116 107 type raw_vuln = { ··· 150 141 rv_affected; 151 142 rv_references; 152 143 }) 153 - |> Object.mem "id" string ~dec_absent:"" ~enc:(fun v -> 154 - v.rv_id) 155 - |> Object.mem "aliases" (list string) 156 - ~dec_absent:[] ~enc:(fun v -> v.rv_aliases) 157 - |> Object.mem "summary" string ~dec_absent:"" 158 - ~enc:(fun v -> v.rv_summary) 159 - |> Object.mem "details" string ~dec_absent:"" 160 - ~enc:(fun v -> v.rv_details) 161 - |> Object.mem "severity" (list severity_entry_jsont) 162 - ~dec_absent:[] ~enc:(fun v -> v.rv_severity) 163 - |> Object.mem "published" string ~dec_absent:"" 164 - ~enc:(fun v -> v.rv_published) 165 - |> Object.mem "modified" string ~dec_absent:"" 166 - ~enc:(fun v -> v.rv_modified) 167 - |> Object.mem "affected" (list raw_affected_jsont) 168 - ~dec_absent:[] ~enc:(fun v -> v.rv_affected) 169 - |> Object.mem "references" (list reference_jsont) 170 - ~dec_absent:[] ~enc:(fun v -> v.rv_references) 171 - |> Object.skip_unknown |> Object.finish 144 + |> Object.member "id" string ~dec_absent:"" ~enc:(fun v -> v.rv_id) 145 + |> Object.member "aliases" (list string) ~dec_absent:[] ~enc:(fun v -> 146 + v.rv_aliases) 147 + |> Object.member "summary" string ~dec_absent:"" ~enc:(fun v -> v.rv_summary) 148 + |> Object.member "details" string ~dec_absent:"" ~enc:(fun v -> v.rv_details) 149 + |> Object.member "severity" (list severity_entry_jsont) ~dec_absent:[] 150 + ~enc:(fun v -> v.rv_severity) 151 + |> Object.member "published" string ~dec_absent:"" ~enc:(fun v -> 152 + v.rv_published) 153 + |> Object.member "modified" string ~dec_absent:"" ~enc:(fun v -> 154 + v.rv_modified) 155 + |> Object.member "affected" (list raw_affected_jsont) ~dec_absent:[] 156 + ~enc:(fun v -> v.rv_affected) 157 + |> Object.member "references" (list reference_jsont) ~dec_absent:[] 158 + ~enc:(fun v -> v.rv_references) 159 + |> Object.skip_unknown |> Object.seal 172 160 173 161 (* Response: {"vulns": [...]} *) 174 162 type raw_response = { vulns : raw_vuln list } ··· 176 164 let raw_response_jsont : raw_response Json.codec = 177 165 let open Json.Codec in 178 166 Object.map ~kind:"response" (fun vulns -> { vulns }) 179 - |> Object.mem "vulns" (list raw_vuln_jsont) 180 - ~dec_absent:[] ~enc:(fun r -> r.vulns) 181 - |> Object.skip_unknown |> Object.finish 167 + |> Object.member "vulns" (list raw_vuln_jsont) ~dec_absent:[] ~enc:(fun r -> 168 + r.vulns) 169 + |> Object.skip_unknown |> Object.seal 182 170 183 171 (* Batch response: {"results": [{"vulns": [...]}, ...]} *) 184 172 type raw_batch_result = { br_vulns : raw_vuln list } ··· 186 174 let raw_batch_result_jsont : raw_batch_result Json.codec = 187 175 let open Json.Codec in 188 176 Object.map ~kind:"batch_result" (fun br_vulns -> { br_vulns }) 189 - |> Object.mem "vulns" (list raw_vuln_jsont) 190 - ~dec_absent:[] ~enc:(fun r -> r.br_vulns) 191 - |> Object.skip_unknown |> Object.finish 177 + |> Object.member "vulns" (list raw_vuln_jsont) ~dec_absent:[] ~enc:(fun r -> 178 + r.br_vulns) 179 + |> Object.skip_unknown |> Object.seal 192 180 193 181 type raw_batch_response = { results : raw_batch_result list } 194 182 195 183 let raw_batch_response_jsont : raw_batch_response Json.codec = 196 184 let open Json.Codec in 197 185 Object.map ~kind:"batch_response" (fun results -> { results }) 198 - |> Object.mem "results" (list raw_batch_result_jsont) 199 - ~dec_absent:[] ~enc:(fun r -> r.results) 200 - |> Object.skip_unknown |> Object.finish 186 + |> Object.member "results" (list raw_batch_result_jsont) ~dec_absent:[] 187 + ~enc:(fun r -> r.results) 188 + |> Object.skip_unknown |> Object.seal 201 189 202 190 (* ── Convert raw types to public types ─────────────────────────────────── *) 203 191
+1 -1
osv.opam
··· 18 18 "logs" {>= "0.7"} 19 19 "astring" {>= "0.8"} 20 20 "json" {>= "0.1"} 21 - "bytesrw" {>= "0.1"} 22 21 "alcotest" {with-test} 22 + "loc" 23 23 "odoc" {with-doc} 24 24 ] 25 25 build: [