JSONSchex.Ref (jsonschex v0.7.0)

Copy Markdown View Source

Generic selected $ref resolver for JSON-like documents.

resolve_selected/2 walks maps and lists and resolves only $ref nodes that the caller selects. This keeps domain-specific knowledge (for example, OpenAPI Reference Object locations) outside JSONSchex while reusing the same low-level reference mechanics as JSON Schema: URI resolution, JSON Pointer lookup, external loading, base URI propagation, and cycle detection.

Summary

Functions

Resolves selected $ref nodes in a JSON-like document.

Types

loader()

@type loader() :: (String.t() -> loader_result())

loader_result()

@type loader_result() ::
  {:ok, map() | boolean()}
  | {:ok, %{:document => map() | boolean(), optional(:base_uri) => String.t()}}
  | {:error, term()}

selector()

@type selector() :: (list(), map() -> boolean())

Functions

resolve_selected(document, opts)

@spec resolve_selected(
  term(),
  keyword()
) :: {:ok, term()} | {:error, JSONSchex.Ref.Error.t()}

Resolves selected $ref nodes in a JSON-like document.

Options

  • :select — required (path, node -> boolean()) callback. path points to the map containing $ref, not to the $ref key.
  • :base_uri — optional starting base URI/path for resolving relative external references.
  • :loader — optional loader for external resources.

Selected $ref nodes are replaced by the resolved target value. Unselected $ref nodes are preserved unchanged and are not interpreted as references.

Examples

Resolve only the selected local $ref node:

iex> document = %{
...>   "parameter" => %{"$ref" => "#/components/parameters/UserId"},
...>   "schema" => %{"$ref" => "#/components/schemas/User"},
...>   "components" => %{
...>     "parameters" => %{"UserId" => %{"name" => "id", "in" => "path"}},
...>     "schemas" => %{"User" => %{"type" => "object"}}
...>   }
...> }
iex> select = fn
...>   ["parameter"], %{"$ref" => _} -> true
...>   _path, _node -> false
...> end
iex> {:ok, resolved} = JSONSchex.Ref.resolve_selected(document, select: select)
iex> resolved["parameter"]
%{"in" => "path", "name" => "id"}
iex> resolved["schema"]
%{"$ref" => "#/components/schemas/User"}

Resolve a selected external $ref with a loader:

iex> document = %{"parameter" => %{"$ref" => "./common.yaml#/components/parameters/UserId"}}
iex> loader = fn "/api/common.yaml" ->
...>   {:ok, %{"components" => %{"parameters" => %{"UserId" => %{"name" => "id", "in" => "path"}}}}}
...> end
iex> {:ok, resolved} = JSONSchex.Ref.resolve_selected(document,
...>   base_uri: "/api/openapi.yaml",
...>   loader: loader,
...>   select: fn _path, %{"$ref" => _} -> true; _path, _node -> false end
...> )
iex> resolved["parameter"]
%{"in" => "path", "name" => "id"}