From 2a4d1cab8e31b20ab8a3f41b4dce2cd51ce0fb8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20Roch=C3=A9?= Date: Tue, 27 Feb 2024 16:11:22 +0100 Subject: [PATCH] TMP jsonschema: support external references --- lib/generator.ml | 27 +++++++++++++------- tests/mocks/jsonschema_refs.json | 42 ++++++++++++++++++++++++++++++++ tests/smoke.t | 19 +++++++++++++++ 3 files changed, 79 insertions(+), 9 deletions(-) create mode 100644 tests/mocks/jsonschema_refs.json diff --git a/lib/generator.ml b/lib/generator.ml index 3b7c37c..773c599 100644 --- a/lib/generator.ml +++ b/lib/generator.ml @@ -23,17 +23,26 @@ let process_int_type schema = | _ -> failwith "int has unextected format" let get_ref_name ref = - match String.split_on_char '/' ref with + let uri, pointer = + match String.split_on_char '#' ref with + | [ uri; pointer ] -> uri, Some pointer + | [ uri ] -> uri, None + | _ -> failwith (sprintf "Unsupported remote ref value: %s. The URI contains multiple '#'." ref) + in + let name_of_path path = + match path |> String.split_on_char '/' |> List.rev |> List.hd with + | exception _ -> failwith (sprintf "Unsupported ref value: %s" ref) + | name -> name + in + match pointer with + | None -> name_of_path uri + | Some pointer -> + match String.split_on_char '/' pointer with (* OpenAPI defs *) - | [ "#"; "components"; "schemas"; type_name ] -> type_name + | [ ""; "components"; "schemas"; type_name ] -> type_name (* JSON Schema defs *) - | [ "#"; ("$defs" | "definitions"); type_name ] -> type_name - | _ -> - failwith - (Printf.sprintf - "Unsupported ref value: %s. Supported ref URI are: #/components/schemas/* and #/$defs/* and #/definitions/*" - ref - ) + | [ ""; ("$defs" | "definitions"); type_name ] -> type_name + | _ -> name_of_path pointer let output = Buffer.create 16 let input_toplevel_schemas = ref [] diff --git a/tests/mocks/jsonschema_refs.json b/tests/mocks/jsonschema_refs.json new file mode 100644 index 0000000..de2045d --- /dev/null +++ b/tests/mocks/jsonschema_refs.json @@ -0,0 +1,42 @@ +{ + "$id": "https://example.com/schemas/customer", + "type": "object", + "properties": { + "first_name": { + "type": "string" + }, + "last_name": { + "type": "string" + }, + "shipping_address": { + "$ref": "/schemas/address" + }, + "billing_address": { + "$ref": "/schemas/address" + }, + "aa": { + "$ref": "https://example.com/schemas/address" + }, + "bb": { + "$ref": "http://example.com/schemas/address" + }, + "cc": { + "$ref": "http://example.com/schemas#/definitions/address" + }, + "dd": { + "$ref": "http://example.com/schemas#/definitions/address" + }, + "ee": { + "$ref": "#/definitions/schemas/address" + }, + "ff": { + "$ref": "#/definitions/address" + } + }, + "required": [ + "first_name", + "last_name", + "shipping_address", + "billing_address" + ] +} diff --git a/tests/smoke.t b/tests/smoke.t index 00a6e90..2b60b36 100644 --- a/tests/smoke.t +++ b/tests/smoke.t @@ -69,3 +69,22 @@ Generate ATD out of JSON Schema that contains definitions (legacy support) first_name : name; last_name : name; } + +Generate ATD out of JSON Schema that uses references + $ jsonschema2atd --format=jsonschema ./mocks/jsonschema_refs.json + (* Generated by jsonschema2atd *) + type json = abstract + type int64 = int + + type root = { + first_name : string; + last_name : string; + shipping_address : address; + billing_address : address; + ?aa : address option; + ?bb : address option; + ?cc : address option; + ?dd : address option; + ?ee : address option; + ?ff : address option; + }