Packages
oaspec
0.11.0
0.68.0
0.67.0
0.66.0
0.65.0
0.64.0
0.63.0
0.62.0
0.61.0
0.60.0
0.59.0
0.58.1
0.58.0
0.57.0
0.56.0
0.55.0
0.54.0
0.53.0
0.52.0
0.51.0
0.50.0
0.49.0
0.48.0
0.47.0
0.46.0
0.45.0
0.44.0
0.43.0
0.42.0
0.41.0
0.40.0
0.39.0
0.38.0
0.37.0
0.36.0
0.35.0
0.34.0
0.33.0
0.32.0
0.31.0
0.30.0
0.29.0
0.28.0
0.27.0
0.26.0
0.25.0
0.24.0
0.23.0
0.22.0
0.21.0
0.20.0
0.19.0
0.18.0
0.17.0
0.16.0
0.15.0
0.14.0
0.13.0
0.12.0
0.11.0
0.10.0
0.9.0
0.8.0
0.7.0
0.6.3
0.6.1
0.6.0
0.5.0
0.4.0
0.3.0
0.1.3
Generate Gleam code from OpenAPI 3.x specifications
Current section
Files
Jump to
Current section
Files
src/oaspec@openapi@resolver.erl
-module(oaspec@openapi@resolver).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/oaspec/openapi/resolver.gleam").
-export([ref_to_name/1, resolve_schema_ref/2, resolve_schema_refs_in_schema/2]).
-export_type([resolve_error/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-type resolve_error() :: {unresolved_ref, binary()} | {circular_ref, binary()}.
-file("src/oaspec/openapi/resolver.gleam", 21).
?DOC(
" Resolve a $ref string to its schema name.\n"
" Example: \"#/components/schemas/User\" -> \"User\"\n"
).
-spec ref_to_name(binary()) -> binary().
ref_to_name(Ref) ->
_pipe = Ref,
_pipe@1 = gleam@string:split(_pipe, <<"/"/utf8>>),
_pipe@2 = gleam@list:last(_pipe@1),
gleam@result:unwrap(_pipe@2, <<"Unknown"/utf8>>).
-file("src/oaspec/openapi/resolver.gleam", 38).
?DOC(" Internal resolver that tracks visited refs for cycle detection.\n").
-spec resolve_schema_ref_with_seen(
oaspec@openapi@schema:schema_ref(),
oaspec@openapi@spec:open_api_spec(oaspec@openapi@spec:resolved()),
gleam@set:set(binary())
) -> {ok, oaspec@openapi@schema:schema_object()} | {error, resolve_error()}.
resolve_schema_ref_with_seen(Schema_ref, Spec, Seen) ->
case Schema_ref of
{inline, Schema} ->
{ok, Schema};
{reference, Ref, Name} ->
case gleam@set:contains(Seen, Ref) of
true ->
{error, {circular_ref, Ref}};
false ->
New_seen = gleam@set:insert(Seen, Ref),
case erlang:element(5, Spec) of
{some, Components} ->
case gleam_stdlib:map_get(
erlang:element(2, Components),
Name
) of
{ok, {inline, Schema@1}} ->
{ok, Schema@1};
{ok, {reference, Inner_ref, Inner_name}} ->
resolve_schema_ref_with_seen(
{reference, Inner_ref, Inner_name},
Spec,
New_seen
);
{error, _} ->
{error, {unresolved_ref, Ref}}
end;
none ->
{error, {unresolved_ref, Ref}}
end
end
end.
-file("src/oaspec/openapi/resolver.gleam", 30).
?DOC(
" Resolve a SchemaRef to a SchemaObject, looking up $ref in components.\n"
" Tracks seen refs to detect circular references.\n"
).
-spec resolve_schema_ref(
oaspec@openapi@schema:schema_ref(),
oaspec@openapi@spec:open_api_spec(oaspec@openapi@spec:resolved())
) -> {ok, oaspec@openapi@schema:schema_object()} | {error, resolve_error()}.
resolve_schema_ref(Schema_ref, Spec) ->
resolve_schema_ref_with_seen(Schema_ref, Spec, gleam@set:new()).
-file("src/oaspec/openapi/resolver.gleam", 110).
?DOC(" Try to resolve a single ref, keeping it as-is if resolution fails.\n").
-spec resolve_one_ref(
oaspec@openapi@schema:schema_ref(),
oaspec@openapi@spec:open_api_spec(oaspec@openapi@spec:resolved())
) -> oaspec@openapi@schema:schema_ref().
resolve_one_ref(Schema_ref, Spec) ->
case Schema_ref of
{reference, _, _} ->
case resolve_schema_ref(Schema_ref, Spec) of
{ok, Schema} ->
{inline, Schema};
{error, _} ->
Schema_ref
end;
Inline ->
Inline
end.
-file("src/oaspec/openapi/resolver.gleam", 125).
?DOC(" Map a list of schema refs, resolving each.\n").
-spec list_map_ref(
list(oaspec@openapi@schema:schema_ref()),
oaspec@openapi@spec:open_api_spec(oaspec@openapi@spec:resolved())
) -> list(oaspec@openapi@schema:schema_ref()).
list_map_ref(Refs, Spec) ->
gleam@list:map(Refs, fun(R) -> resolve_one_ref(R, Spec) end).
-file("src/oaspec/openapi/resolver.gleam", 72).
?DOC(" Resolve all $ref in a schema object's nested schemas (one level).\n").
-spec resolve_schema_refs_in_schema(
oaspec@openapi@schema:schema_object(),
oaspec@openapi@spec:open_api_spec(oaspec@openapi@spec:resolved())
) -> oaspec@openapi@schema:schema_object().
resolve_schema_refs_in_schema(Schema, Spec) ->
case Schema of
{object_schema, _, Properties, _, Additional_properties, _, _} = Obj ->
Resolved_props = gleam@dict:map_values(
Properties,
fun(_, V) -> resolve_one_ref(V, Spec) end
),
Resolved_ap = case Additional_properties of
{typed, Ap} ->
{typed, resolve_one_ref(Ap, Spec)};
untyped ->
untyped;
forbidden ->
forbidden
end,
{object_schema,
erlang:element(2, Obj),
Resolved_props,
erlang:element(4, Obj),
Resolved_ap,
erlang:element(6, Obj),
erlang:element(7, Obj)};
{array_schema, _, Items, _, _, _} = Arr ->
{array_schema,
erlang:element(2, Arr),
resolve_one_ref(Items, Spec),
erlang:element(4, Arr),
erlang:element(5, Arr),
erlang:element(6, Arr)};
{all_of_schema, Metadata, Schemas} ->
Resolved = list_map_ref(Schemas, Spec),
{all_of_schema, Metadata, Resolved};
{one_of_schema, Metadata@1, Schemas@1, Discriminator} ->
Resolved@1 = list_map_ref(Schemas@1, Spec),
{one_of_schema, Metadata@1, Resolved@1, Discriminator};
{any_of_schema, Metadata@2, Schemas@2, Discriminator@1} ->
Resolved@2 = list_map_ref(Schemas@2, Spec),
{any_of_schema, Metadata@2, Resolved@2, Discriminator@1};
Other ->
Other
end.