OSV.dev vulnerability database client
0
fork

Configure Feed

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

ocaml-osv: migrate to new Json API

Wrap Json.Error.t with Json.Error.to_string where per-package string
error types cross module boundaries. Internal propagation of Json.Error.t
stays structured.

+64 -60
+64 -60
lib/osv.ml
··· 55 55 type severity_entry = { sev_type : string; score : string } 56 56 57 57 let severity_entry_jsont : severity_entry Json.codec = 58 - Json.Object.map ~kind:"severity_entry" (fun sev_type score -> 58 + Json.Codec.Object.map ~kind:"severity_entry" (fun sev_type score -> 59 59 { sev_type; score }) 60 - |> Json.Object.mem "type" Json.string ~dec_absent:"" ~enc:(fun s -> 61 - s.sev_type) 62 - |> Json.Object.mem "score" Json.string ~dec_absent:"" ~enc:(fun s -> 63 - s.score) 64 - |> Json.Object.skip_unknown |> Json.Object.finish 60 + |> Json.Codec.Object.mem "type" Json.Codec.string ~dec_absent:"" 61 + ~enc:(fun s -> s.sev_type) 62 + |> Json.Codec.Object.mem "score" Json.Codec.string ~dec_absent:"" 63 + ~enc:(fun s -> s.score) 64 + |> Json.Codec.Object.skip_unknown |> Json.Codec.Object.finish 65 65 66 66 (* Reference: {"type": "WEB", "url": "https://..."} *) 67 67 let reference_jsont : reference Json.codec = 68 - Json.Object.map ~kind:"reference" (fun ref_type url -> { ref_type; url }) 69 - |> Json.Object.mem "type" Json.string ~dec_absent:"" ~enc:(fun r -> 70 - r.ref_type) 71 - |> Json.Object.mem "url" Json.string ~dec_absent:"" ~enc:(fun r -> r.url) 72 - |> Json.Object.skip_unknown |> Json.Object.finish 68 + Json.Codec.Object.map ~kind:"reference" (fun ref_type url -> 69 + { ref_type; url }) 70 + |> Json.Codec.Object.mem "type" Json.Codec.string ~dec_absent:"" 71 + ~enc:(fun r -> r.ref_type) 72 + |> Json.Codec.Object.mem "url" Json.Codec.string ~dec_absent:"" ~enc:(fun r -> 73 + r.url) 74 + |> Json.Codec.Object.skip_unknown |> Json.Codec.Object.finish 73 75 74 76 (* Event: {"introduced": "0", "fixed": "1.2.3"} *) 75 77 type range_event = { event_type : string; event_version : string } 76 78 77 79 let range_event_jsont : range_event Json.codec = 78 80 (* Events are objects with a single key being the event type *) 79 - Json.Object.map ~kind:"range_event" (fun event_type event_version -> 81 + Json.Codec.Object.map ~kind:"range_event" (fun event_type event_version -> 80 82 { event_type; event_version }) 81 - |> Json.Object.mem "introduced" Json.string ~dec_absent:"" ~enc:(fun e -> 82 - e.event_type) 83 - |> Json.Object.mem "fixed" Json.string ~dec_absent:"" ~enc:(fun e -> 84 - e.event_version) 85 - |> Json.Object.skip_unknown |> Json.Object.finish 83 + |> Json.Codec.Object.mem "introduced" Json.Codec.string ~dec_absent:"" 84 + ~enc:(fun e -> e.event_type) 85 + |> Json.Codec.Object.mem "fixed" Json.Codec.string ~dec_absent:"" 86 + ~enc:(fun e -> e.event_version) 87 + |> Json.Codec.Object.skip_unknown |> Json.Codec.Object.finish 86 88 87 89 (* Range: {"type": "SEMVER", "events": [...]} *) 88 90 type raw_range = { rr_type : string; events : range_event list } 89 91 90 92 let raw_range_jsont : raw_range Json.codec = 91 - Json.Object.map ~kind:"range" (fun rr_type events -> { rr_type; events }) 92 - |> Json.Object.mem "type" Json.string ~dec_absent:"" ~enc:(fun r -> 93 - r.rr_type) 94 - |> Json.Object.mem "events" (Json.list range_event_jsont) ~dec_absent:[] 95 - ~enc:(fun r -> r.events) 96 - |> Json.Object.skip_unknown |> Json.Object.finish 93 + Json.Codec.Object.map ~kind:"range" (fun rr_type events -> 94 + { rr_type; events }) 95 + |> Json.Codec.Object.mem "type" Json.Codec.string ~dec_absent:"" 96 + ~enc:(fun r -> r.rr_type) 97 + |> Json.Codec.Object.mem "events" (Json.Codec.list range_event_jsont) 98 + ~dec_absent:[] ~enc:(fun r -> r.events) 99 + |> Json.Codec.Object.skip_unknown |> Json.Codec.Object.finish 97 100 98 101 (* Affected: {"ranges": [...]} *) 99 102 type raw_affected = { ranges : raw_range list } 100 103 101 104 let raw_affected_jsont : raw_affected Json.codec = 102 - Json.Object.map ~kind:"affected" (fun ranges -> { ranges }) 103 - |> Json.Object.mem "ranges" (Json.list raw_range_jsont) ~dec_absent:[] 104 - ~enc:(fun a -> a.ranges) 105 - |> Json.Object.skip_unknown |> Json.Object.finish 105 + Json.Codec.Object.map ~kind:"affected" (fun ranges -> { ranges }) 106 + |> Json.Codec.Object.mem "ranges" (Json.Codec.list raw_range_jsont) 107 + ~dec_absent:[] ~enc:(fun a -> a.ranges) 108 + |> Json.Codec.Object.skip_unknown |> Json.Codec.Object.finish 106 109 107 110 (* Vulnerability (top-level OSV record) *) 108 111 type raw_vuln = { ··· 118 121 } 119 122 120 123 let raw_vuln_jsont : raw_vuln Json.codec = 121 - Json.Object.map ~kind:"vulnerability" 124 + Json.Codec.Object.map ~kind:"vulnerability" 122 125 (fun 123 126 rv_id 124 127 rv_aliases ··· 141 144 rv_affected; 142 145 rv_references; 143 146 }) 144 - |> Json.Object.mem "id" Json.string ~dec_absent:"" ~enc:(fun v -> v.rv_id) 145 - |> Json.Object.mem "aliases" (Json.list Json.string) ~dec_absent:[] 146 - ~enc:(fun v -> v.rv_aliases) 147 - |> Json.Object.mem "summary" Json.string ~dec_absent:"" ~enc:(fun v -> 148 - v.rv_summary) 149 - |> Json.Object.mem "details" Json.string ~dec_absent:"" ~enc:(fun v -> 150 - v.rv_details) 151 - |> Json.Object.mem "severity" (Json.list severity_entry_jsont) 147 + |> Json.Codec.Object.mem "id" Json.Codec.string ~dec_absent:"" ~enc:(fun v -> 148 + v.rv_id) 149 + |> Json.Codec.Object.mem "aliases" (Json.Codec.list Json.Codec.string) 150 + ~dec_absent:[] ~enc:(fun v -> v.rv_aliases) 151 + |> Json.Codec.Object.mem "summary" Json.Codec.string ~dec_absent:"" 152 + ~enc:(fun v -> v.rv_summary) 153 + |> Json.Codec.Object.mem "details" Json.Codec.string ~dec_absent:"" 154 + ~enc:(fun v -> v.rv_details) 155 + |> Json.Codec.Object.mem "severity" (Json.Codec.list severity_entry_jsont) 152 156 ~dec_absent:[] ~enc:(fun v -> v.rv_severity) 153 - |> Json.Object.mem "published" Json.string ~dec_absent:"" ~enc:(fun v -> 154 - v.rv_published) 155 - |> Json.Object.mem "modified" Json.string ~dec_absent:"" ~enc:(fun v -> 156 - v.rv_modified) 157 - |> Json.Object.mem "affected" (Json.list raw_affected_jsont) ~dec_absent:[] 158 - ~enc:(fun v -> v.rv_affected) 159 - |> Json.Object.mem "references" (Json.list reference_jsont) ~dec_absent:[] 160 - ~enc:(fun v -> v.rv_references) 161 - |> Json.Object.skip_unknown |> Json.Object.finish 157 + |> Json.Codec.Object.mem "published" Json.Codec.string ~dec_absent:"" 158 + ~enc:(fun v -> v.rv_published) 159 + |> Json.Codec.Object.mem "modified" Json.Codec.string ~dec_absent:"" 160 + ~enc:(fun v -> v.rv_modified) 161 + |> Json.Codec.Object.mem "affected" (Json.Codec.list raw_affected_jsont) 162 + ~dec_absent:[] ~enc:(fun v -> v.rv_affected) 163 + |> Json.Codec.Object.mem "references" (Json.Codec.list reference_jsont) 164 + ~dec_absent:[] ~enc:(fun v -> v.rv_references) 165 + |> Json.Codec.Object.skip_unknown |> Json.Codec.Object.finish 162 166 163 167 (* Response: {"vulns": [...]} *) 164 168 type raw_response = { vulns : raw_vuln list } 165 169 166 170 let raw_response_jsont : raw_response Json.codec = 167 - Json.Object.map ~kind:"response" (fun vulns -> { vulns }) 168 - |> Json.Object.mem "vulns" (Json.list raw_vuln_jsont) ~dec_absent:[] 169 - ~enc:(fun r -> r.vulns) 170 - |> Json.Object.skip_unknown |> Json.Object.finish 171 + Json.Codec.Object.map ~kind:"response" (fun vulns -> { vulns }) 172 + |> Json.Codec.Object.mem "vulns" (Json.Codec.list raw_vuln_jsont) 173 + ~dec_absent:[] ~enc:(fun r -> r.vulns) 174 + |> Json.Codec.Object.skip_unknown |> Json.Codec.Object.finish 171 175 172 176 (* Batch response: {"results": [{"vulns": [...]}, ...]} *) 173 177 type raw_batch_result = { br_vulns : raw_vuln list } 174 178 175 179 let raw_batch_result_jsont : raw_batch_result Json.codec = 176 - Json.Object.map ~kind:"batch_result" (fun br_vulns -> { br_vulns }) 177 - |> Json.Object.mem "vulns" (Json.list raw_vuln_jsont) ~dec_absent:[] 178 - ~enc:(fun r -> r.br_vulns) 179 - |> Json.Object.skip_unknown |> Json.Object.finish 180 + Json.Codec.Object.map ~kind:"batch_result" (fun br_vulns -> { br_vulns }) 181 + |> Json.Codec.Object.mem "vulns" (Json.Codec.list raw_vuln_jsont) 182 + ~dec_absent:[] ~enc:(fun r -> r.br_vulns) 183 + |> Json.Codec.Object.skip_unknown |> Json.Codec.Object.finish 180 184 181 185 type raw_batch_response = { results : raw_batch_result list } 182 186 183 187 let raw_batch_response_jsont : raw_batch_response Json.codec = 184 - Json.Object.map ~kind:"batch_response" (fun results -> { results }) 185 - |> Json.Object.mem "results" (Json.list raw_batch_result_jsont) 188 + Json.Codec.Object.map ~kind:"batch_response" (fun results -> { results }) 189 + |> Json.Codec.Object.mem "results" (Json.Codec.list raw_batch_result_jsont) 186 190 ~dec_absent:[] ~enc:(fun r -> r.results) 187 - |> Json.Object.skip_unknown |> Json.Object.finish 191 + |> Json.Codec.Object.skip_unknown |> Json.Codec.Object.finish 188 192 189 193 (* ── Convert raw types to public types ─────────────────────────────────── *) 190 194 ··· 234 238 (* ── Response parsing ──────────────────────────────────────────────────── *) 235 239 236 240 let parse_response json = 237 - match Json_bytesrw.decode_string raw_response_jsont json with 241 + match Json.of_string raw_response_jsont json with 238 242 | Ok resp -> List.map vuln_of_raw resp.vulns 239 243 | Error msg -> 240 - Log.err (fun f -> f "parse_response: %s" msg); 244 + Log.err (fun f -> f "parse_response: %s" (Json.Error.to_string msg)); 241 245 [] 242 246 243 247 (* ── HTTP helpers ──────────────────────────────────────────────────────── *) ··· 293 297 Log.err (fun f -> f "batch query failed: %s" msg); 294 298 List.map (fun purl -> (purl, [])) purls 295 299 | Ok json -> ( 296 - match Json_bytesrw.decode_string raw_batch_response_jsont json with 300 + match Json.of_string raw_batch_response_jsont json with 297 301 | Error msg -> 298 - Log.err (fun f -> f "batch parse failed: %s" msg); 302 + Log.err (fun f -> f "batch parse failed: %s" (Json.Error.to_string msg)); 299 303 List.map (fun purl -> (purl, [])) purls 300 304 | Ok resp -> 301 305 let parsed =