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@resolve.erl
-module(oaspec@openapi@resolve).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/oaspec/openapi/resolve.gleam").
-export([resolve/1]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-file("src/oaspec/openapi/resolve.gleam", 186).
?DOC(" Extract the last segment of a $ref path.\n").
-spec extract_ref_name(binary()) -> binary().
extract_ref_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/resolve.gleam", 147).
?DOC(" Follow a $ref chain to find the concrete value.\n").
-spec resolve_alias(
gleam@dict:dict(binary(), oaspec@openapi@spec:ref_or(OUE)),
binary(),
binary(),
gleam@set:set(binary())
) -> {ok, OUE} | {error, oaspec@openapi@diagnostic:diagnostic()}.
resolve_alias(Entries, Ref, Context, Seen) ->
case gleam@set:contains(Seen, Ref) of
true ->
{error,
oaspec@openapi@diagnostic:resolve_error(
Context,
<<"Circular component alias detected: "/utf8, Ref/binary>>,
{some,
<<"Check that component $ref chains don't form a cycle. Each $ref must eventually point to a concrete definition."/utf8>>}
)};
false ->
New_seen = gleam@set:insert(Seen, Ref),
Ref_name = extract_ref_name(Ref),
case gleam_stdlib:map_get(Entries, Ref_name) of
{ok, {value, Value}} ->
{ok, Value};
{ok, {ref, Next_ref}} ->
resolve_alias(Entries, Next_ref, Context, New_seen);
{error, _} ->
{error,
oaspec@openapi@diagnostic:resolve_error(
Context,
<<<<<<<<"Unresolved component alias: "/utf8,
Ref/binary>>/binary,
" — target '"/utf8>>/binary,
Ref_name/binary>>/binary,
"' not found."/utf8>>,
{some,
<<"Verify the target component exists and the $ref path is spelled correctly."/utf8>>}
)}
end
end.
-file("src/oaspec/openapi/resolve.gleam", 124).
?DOC(
" Resolve all aliases in a component dict.\n"
" After resolution, all entries are Value.\n"
).
-spec resolve_component_dict(
gleam@dict:dict(binary(), oaspec@openapi@spec:ref_or(OTV)),
binary()
) -> {ok, gleam@dict:dict(binary(), oaspec@openapi@spec:ref_or(OTV))} |
{error, oaspec@openapi@diagnostic:diagnostic()}.
resolve_component_dict(Entries, Context) ->
_pipe = maps:to_list(Entries),
gleam@list:try_fold(
_pipe,
Entries,
fun(Acc, Entry) ->
{Name, Value} = Entry,
case Value of
{value, _} ->
{ok, Acc};
{ref, Ref} ->
gleam@result:'try'(
resolve_alias(
Entries,
Ref,
<<<<Context/binary, "."/utf8>>/binary, Name/binary>>,
gleam@set:new()
),
fun(Resolved) ->
{ok,
gleam@dict:insert(Acc, Name, {value, Resolved})}
end
)
end
end
).
-file("src/oaspec/openapi/resolve.gleam", 195).
?DOC(
" Validate that a $ref string points to the expected component kind.\n"
" Returns Ok(name) if valid, Error(diagnostic) if wrong kind or external.\n"
).
-spec validate_ref_kind(binary(), binary(), binary()) -> {ok, binary()} |
{error, oaspec@openapi@diagnostic:diagnostic()}.
validate_ref_kind(Ref_str, Expected_prefix, Context_path) ->
case gleam_stdlib:string_starts_with(Ref_str, Expected_prefix) of
true ->
{ok, extract_ref_name(Ref_str)};
false ->
{error,
oaspec@openapi@diagnostic:resolve_error(
Context_path,
<<<<<<<<"$ref '"/utf8, Ref_str/binary>>/binary,
"' points to wrong component kind; expected prefix '"/utf8>>/binary,
Expected_prefix/binary>>/binary,
"'"/utf8>>,
{some,
<<"Use the correct $ref prefix for the component type (e.g., #/components/schemas/ for schemas)."/utf8>>}
)}
end.
-file("src/oaspec/openapi/resolve.gleam", 415).
?DOC(" Resolve a parameter Ref by looking it up in components.parameters.\n").
-spec resolve_param_ref(
oaspec@openapi@spec:ref_or(oaspec@openapi@spec:parameter(OWB)),
binary(),
oaspec@openapi@spec:components(OWB)
) -> {ok, oaspec@openapi@spec:ref_or(oaspec@openapi@spec:parameter(OWB))} |
{error, oaspec@openapi@diagnostic:diagnostic()}.
resolve_param_ref(Ref_or, Path, Components) ->
case Ref_or of
{value, _} ->
{ok, Ref_or};
{ref, Ref_str} ->
gleam@result:'try'(
validate_ref_kind(
Ref_str,
<<"#/components/parameters/"/utf8>>,
<<"paths."/utf8, Path/binary>>
),
fun(Ref_name) ->
case gleam_stdlib:map_get(
erlang:element(3, Components),
Ref_name
) of
{ok, {value, P}} ->
{ok, {value, P}};
_ ->
{error,
oaspec@openapi@diagnostic:resolve_error(
<<"paths."/utf8, Path/binary>>,
<<<<"Unresolved $ref: "/utf8,
Ref_str/binary>>/binary,
" — target not found in components.parameters"/utf8>>,
{some,
<<"Verify the parameter exists in components.parameters."/utf8>>}
)}
end
end
)
end.
-file("src/oaspec/openapi/resolve.gleam", 444).
?DOC(" Resolve a request body Ref by looking it up in components.request_bodies.\n").
-spec resolve_request_body_ref(
oaspec@openapi@spec:ref_or(oaspec@openapi@spec:request_body(OWJ)),
binary(),
oaspec@openapi@spec:components(OWJ)
) -> {ok, oaspec@openapi@spec:ref_or(oaspec@openapi@spec:request_body(OWJ))} |
{error, oaspec@openapi@diagnostic:diagnostic()}.
resolve_request_body_ref(Ref_or, Path, Components) ->
case Ref_or of
{value, _} ->
{ok, Ref_or};
{ref, Ref_str} ->
gleam@result:'try'(
validate_ref_kind(
Ref_str,
<<"#/components/requestBodies/"/utf8>>,
<<"paths."/utf8, Path/binary>>
),
fun(Ref_name) ->
case gleam_stdlib:map_get(
erlang:element(4, Components),
Ref_name
) of
{ok, {value, Rb}} ->
{ok, {value, Rb}};
_ ->
{error,
oaspec@openapi@diagnostic:resolve_error(
<<"paths."/utf8, Path/binary>>,
<<<<"Unresolved $ref: "/utf8,
Ref_str/binary>>/binary,
" — target not found in components.requestBodies"/utf8>>,
{some,
<<"Verify the request body exists in components.requestBodies."/utf8>>}
)}
end
end
)
end.
-file("src/oaspec/openapi/resolve.gleam", 475).
?DOC(" Resolve a response Ref by looking it up in components.responses.\n").
-spec resolve_response_ref(
oaspec@openapi@spec:ref_or(oaspec@openapi@spec:response(OWR)),
binary(),
oaspec@openapi@spec:components(OWR)
) -> {ok, oaspec@openapi@spec:ref_or(oaspec@openapi@spec:response(OWR))} |
{error, oaspec@openapi@diagnostic:diagnostic()}.
resolve_response_ref(Ref_or, Path, Components) ->
case Ref_or of
{value, _} ->
{ok, Ref_or};
{ref, Ref_str} ->
gleam@result:'try'(
validate_ref_kind(
Ref_str,
<<"#/components/responses/"/utf8>>,
<<"paths."/utf8, Path/binary>>
),
fun(Ref_name) ->
case gleam_stdlib:map_get(
erlang:element(5, Components),
Ref_name
) of
{ok, {value, R}} ->
{ok, {value, R}};
_ ->
{error,
oaspec@openapi@diagnostic:resolve_error(
<<"paths."/utf8, Path/binary>>,
<<<<"Unresolved $ref: "/utf8,
Ref_str/binary>>/binary,
" — target not found in components.responses"/utf8>>,
{some,
<<"Verify the response exists in components.responses."/utf8>>}
)}
end
end
)
end.
-file("src/oaspec/openapi/resolve.gleam", 504).
?DOC(" Map over an Option value with a fallible function.\n").
-spec option_try(
gleam@option:option(OWZ),
fun((OWZ) -> {ok, OWZ} |
{error, list(oaspec@openapi@diagnostic:diagnostic())})
) -> {ok, gleam@option:option(OWZ)} |
{error, list(oaspec@openapi@diagnostic:diagnostic())}.
option_try(Opt, F) ->
case Opt of
{some, V} ->
gleam@result:map(F(V), fun(Field@0) -> {some, Field@0} end);
none ->
{ok, none}
end.
-file("src/oaspec/openapi/resolve.gleam", 515).
?DOC(" Map over dict values with a fallible function, collecting first error.\n").
-spec try_map_values(
gleam@dict:dict(OXI, OXJ),
fun((OXI, OXJ) -> {ok, OXJ} |
{error, list(oaspec@openapi@diagnostic:diagnostic())})
) -> {ok, gleam@dict:dict(OXI, OXJ)} |
{error, list(oaspec@openapi@diagnostic:diagnostic())}.
try_map_values(D, F) ->
_pipe = maps:to_list(D),
gleam@list:try_fold(
_pipe,
maps:new(),
fun(Acc, Entry) ->
{Key, Value} = Entry,
gleam@result:'try'(
F(Key, Value),
fun(New_value) ->
{ok, gleam@dict:insert(Acc, Key, New_value)}
end
)
end
).
-file("src/oaspec/openapi/resolve.gleam", 392).
?DOC(" Resolve inline refs within a callback.\n").
-spec resolve_inline_callback(
oaspec@openapi@spec:callback(OVU),
binary(),
oaspec@openapi@spec:components(OVU)
) -> {ok, oaspec@openapi@spec:callback(OVU)} |
{error, list(oaspec@openapi@diagnostic:diagnostic())}.
resolve_inline_callback(Cb, Path, Components) ->
gleam@result:'try'(
try_map_values(erlang:element(2, Cb), fun(_, Ref_or) -> case Ref_or of
{ref, Ref_str} ->
_pipe = resolve_path_item_ref(Ref_str, Path, Components),
gleam@result:map_error(_pipe, fun(E) -> [E] end);
{value, Pi} ->
case resolve_inline_path_item(Pi, Path, Components) of
{ok, Resolved_pi} ->
{ok, {value, Resolved_pi}};
{error, Errs} ->
{error, Errs}
end
end end),
fun(Entries) -> {ok, {callback, Entries}} end
).
-file("src/oaspec/openapi/resolve.gleam", 245).
?DOC(" Resolve a path-level $ref by looking it up in components.pathItems.\n").
-spec resolve_path_item_ref(
binary(),
binary(),
oaspec@openapi@spec:components(OVA)
) -> {ok, oaspec@openapi@spec:ref_or(oaspec@openapi@spec:path_item(OVA))} |
{error, oaspec@openapi@diagnostic:diagnostic()}.
resolve_path_item_ref(Ref_str, Path, Components) ->
gleam@result:'try'(
validate_ref_kind(
Ref_str,
<<"#/components/pathItems/"/utf8>>,
<<"paths."/utf8, Path/binary>>
),
fun(Ref_name) ->
case gleam_stdlib:map_get(erlang:element(7, Components), Ref_name) of
{ok, {value, Pi}} ->
case resolve_inline_path_item(Pi, Path, Components) of
{ok, Resolved_pi} ->
{ok, {value, Resolved_pi}};
{error, Errs} ->
case Errs of
[First | _] ->
{error, First};
[] ->
{error,
oaspec@openapi@diagnostic:resolve_error(
<<"paths."/utf8, Path/binary>>,
<<<<"Unresolved $ref: "/utf8,
Ref_str/binary>>/binary,
" — target not found in components"/utf8>>,
{some,
<<"Verify the referenced component exists and the $ref path is spelled correctly."/utf8>>}
)}
end
end;
{ok, {ref, _}} ->
{error,
oaspec@openapi@diagnostic:resolve_error(
<<"paths."/utf8, Path/binary>>,
<<<<"Unresolved $ref: "/utf8, Ref_str/binary>>/binary,
" — target not found in components"/utf8>>,
{some,
<<"Verify the referenced component exists and the $ref path is spelled correctly."/utf8>>}
)};
{error, _} ->
{error,
oaspec@openapi@diagnostic:resolve_error(
<<"paths."/utf8, Path/binary>>,
<<<<"Unresolved $ref: "/utf8, Ref_str/binary>>/binary,
" — target not found in components"/utf8>>,
{some,
<<"Verify the referenced component exists and the $ref path is spelled correctly."/utf8>>}
)}
end
end
).
-file("src/oaspec/openapi/resolve.gleam", 300).
?DOC(" Resolve inline refs within a path item.\n").
-spec resolve_inline_path_item(
oaspec@openapi@spec:path_item(OVG),
binary(),
oaspec@openapi@spec:components(OVG)
) -> {ok, oaspec@openapi@spec:path_item(OVG)} |
{error, list(oaspec@openapi@diagnostic:diagnostic())}.
resolve_inline_path_item(Pi, Path, Components) ->
gleam@result:'try'(
option_try(
erlang:element(4, Pi),
fun(_capture) ->
resolve_inline_operation(_capture, Path, Components)
end
),
fun(Get) ->
gleam@result:'try'(
option_try(
erlang:element(5, Pi),
fun(_capture@1) ->
resolve_inline_operation(_capture@1, Path, Components)
end
),
fun(Post) ->
gleam@result:'try'(
option_try(
erlang:element(6, Pi),
fun(_capture@2) ->
resolve_inline_operation(
_capture@2,
Path,
Components
)
end
),
fun(Put) ->
gleam@result:'try'(
option_try(
erlang:element(7, Pi),
fun(_capture@3) ->
resolve_inline_operation(
_capture@3,
Path,
Components
)
end
),
fun(Delete) ->
gleam@result:'try'(
option_try(
erlang:element(8, Pi),
fun(_capture@4) ->
resolve_inline_operation(
_capture@4,
Path,
Components
)
end
),
fun(Patch) ->
gleam@result:'try'(
option_try(
erlang:element(9, Pi),
fun(_capture@5) ->
resolve_inline_operation(
_capture@5,
Path,
Components
)
end
),
fun(Head) ->
gleam@result:'try'(
option_try(
erlang:element(
10,
Pi
),
fun(_capture@6) ->
resolve_inline_operation(
_capture@6,
Path,
Components
)
end
),
fun(Options) ->
gleam@result:'try'(
option_try(
erlang:element(
11,
Pi
),
fun(
_capture@7
) ->
resolve_inline_operation(
_capture@7,
Path,
Components
)
end
),
fun(Trace) ->
gleam@result:'try'(
gleam@list:try_map(
erlang:element(
12,
Pi
),
fun(
P
) ->
_pipe = resolve_param_ref(
P,
Path,
Components
),
gleam@result:map_error(
_pipe,
fun(
E
) ->
[E]
end
)
end
),
fun(
Parameters
) ->
{ok,
{path_item,
erlang:element(
2,
Pi
),
erlang:element(
3,
Pi
),
Get,
Post,
Put,
Delete,
Patch,
Head,
Options,
Trace,
Parameters,
erlang:element(
13,
Pi
)}}
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
).
-file("src/oaspec/openapi/resolve.gleam", 352).
?DOC(" Resolve inline refs within an operation.\n").
-spec resolve_inline_operation(
oaspec@openapi@spec:operation(OVN),
binary(),
oaspec@openapi@spec:components(OVN)
) -> {ok, oaspec@openapi@spec:operation(OVN)} |
{error, list(oaspec@openapi@diagnostic:diagnostic())}.
resolve_inline_operation(Op, Path, Components) ->
gleam@result:'try'(
gleam@list:try_map(
erlang:element(6, Op),
fun(P) -> _pipe = resolve_param_ref(P, Path, Components),
gleam@result:map_error(_pipe, fun(E) -> [E] end) end
),
fun(Parameters) ->
gleam@result:'try'(
option_try(
erlang:element(7, Op),
fun(Rb) ->
_pipe@1 = resolve_request_body_ref(Rb, Path, Components),
gleam@result:map_error(_pipe@1, fun(E@1) -> [E@1] end)
end
),
fun(Request_body) ->
gleam@result:'try'(
try_map_values(
erlang:element(8, Op),
fun(_, Ref_or) ->
_pipe@2 = resolve_response_ref(
Ref_or,
Path,
Components
),
gleam@result:map_error(
_pipe@2,
fun(E@2) -> [E@2] end
)
end
),
fun(Responses) ->
gleam@result:'try'(
try_map_values(
erlang:element(11, Op),
fun(_, Cb) ->
resolve_inline_callback(
Cb,
Path,
Components
)
end
),
fun(Callbacks) ->
{ok,
{operation,
erlang:element(2, Op),
erlang:element(3, Op),
erlang:element(4, Op),
erlang:element(5, Op),
Parameters,
Request_body,
Responses,
erlang:element(9, Op),
erlang:element(10, Op),
Callbacks,
erlang:element(12, Op),
erlang:element(13, Op)}}
end
)
end
)
end
)
end
).
-file("src/oaspec/openapi/resolve.gleam", 222).
?DOC(" Resolve inline refs in a paths dict by looking up components.\n").
-spec resolve_inline_paths(
gleam@dict:dict(binary(), oaspec@openapi@spec:ref_or(oaspec@openapi@spec:path_item(OUN))),
oaspec@openapi@spec:components(OUN)
) -> {ok,
gleam@dict:dict(binary(), oaspec@openapi@spec:ref_or(oaspec@openapi@spec:path_item(OUN)))} |
{error, list(oaspec@openapi@diagnostic:diagnostic())}.
resolve_inline_paths(Paths, Components) ->
_pipe = maps:to_list(Paths),
gleam@list:try_fold(
_pipe,
maps:new(),
fun(Acc, Entry) ->
{Path, Ref_or} = Entry,
case Ref_or of
{ref, Ref_str} ->
case resolve_path_item_ref(Ref_str, Path, Components) of
{ok, Resolved} ->
{ok, gleam@dict:insert(Acc, Path, Resolved)};
{error, E} ->
{error, [E]}
end;
{value, Pi} ->
case resolve_inline_path_item(Pi, Path, Components) of
{ok, Resolved_pi} ->
{ok,
gleam@dict:insert(
Acc,
Path,
{value, Resolved_pi}
)};
{error, Errs} ->
{error, Errs}
end
end
end
).
-file("src/oaspec/openapi/resolve.gleam", 30).
?DOC(" Internal resolve that preserves the input stage parameter.\n").
-spec resolve_internal(oaspec@openapi@spec:open_api_spec(OTP)) -> {ok,
oaspec@openapi@spec:open_api_spec(OTP)} |
{error, list(oaspec@openapi@diagnostic:diagnostic())}.
resolve_internal(Spec) ->
Empty_components = {components,
maps:new(),
maps:new(),
maps:new(),
maps:new(),
maps:new(),
maps:new(),
maps:new(),
maps:new(),
maps:new()},
case erlang:element(5, Spec) of
none ->
gleam@result:'try'(
resolve_inline_paths(erlang:element(4, Spec), Empty_components),
fun(Resolved_paths) ->
gleam@result:'try'(
resolve_inline_paths(
erlang:element(8, Spec),
Empty_components
),
fun(Resolved_webhooks) ->
{ok,
{open_api_spec,
erlang:element(2, Spec),
erlang:element(3, Spec),
Resolved_paths,
erlang:element(5, Spec),
erlang:element(6, Spec),
erlang:element(7, Spec),
Resolved_webhooks,
erlang:element(9, Spec),
erlang:element(10, Spec),
erlang:element(11, Spec)}}
end
)
end
);
{some, Components} ->
gleam@result:'try'(
begin
_pipe = resolve_component_dict(
erlang:element(3, Components),
<<"components.parameters"/utf8>>
),
gleam@result:map_error(_pipe, fun(E) -> [E] end)
end,
fun(Parameters) ->
gleam@result:'try'(
begin
_pipe@1 = resolve_component_dict(
erlang:element(4, Components),
<<"components.requestBodies"/utf8>>
),
gleam@result:map_error(
_pipe@1,
fun(E@1) -> [E@1] end
)
end,
fun(Request_bodies) ->
gleam@result:'try'(
begin
_pipe@2 = resolve_component_dict(
erlang:element(5, Components),
<<"components.responses"/utf8>>
),
gleam@result:map_error(
_pipe@2,
fun(E@2) -> [E@2] end
)
end,
fun(Responses) ->
gleam@result:'try'(
begin
_pipe@3 = resolve_component_dict(
erlang:element(6, Components),
<<"components.securitySchemes"/utf8>>
),
gleam@result:map_error(
_pipe@3,
fun(E@3) -> [E@3] end
)
end,
fun(Security_schemes) ->
gleam@result:'try'(
begin
_pipe@4 = resolve_component_dict(
erlang:element(
7,
Components
),
<<"components.pathItems"/utf8>>
),
gleam@result:map_error(
_pipe@4,
fun(E@4) -> [E@4] end
)
end,
fun(Path_items) ->
Resolved_components = {components,
erlang:element(
2,
Components
),
Parameters,
Request_bodies,
Responses,
Security_schemes,
Path_items,
erlang:element(
8,
Components
),
erlang:element(
9,
Components
),
erlang:element(
10,
Components
)},
gleam@result:'try'(
resolve_inline_paths(
erlang:element(
4,
Spec
),
Resolved_components
),
fun(Resolved_paths@1) ->
gleam@result:'try'(
resolve_inline_paths(
erlang:element(
8,
Spec
),
Resolved_components
),
fun(
Resolved_webhooks@1
) ->
{ok,
{open_api_spec,
erlang:element(
2,
Spec
),
erlang:element(
3,
Spec
),
Resolved_paths@1,
{some,
Resolved_components},
erlang:element(
6,
Spec
),
erlang:element(
7,
Spec
),
Resolved_webhooks@1,
erlang:element(
9,
Spec
),
erlang:element(
10,
Spec
),
erlang:element(
11,
Spec
)}}
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end.
-file("src/oaspec/openapi/resolve.gleam", 18).
?DOC(
" Resolve all RefOr aliases in the spec.\n"
" Call after parse and normalize, before capability_check and codegen.\n"
" Resolves both component-level aliases and inline $ref within operations.\n"
).
-spec resolve(
oaspec@openapi@spec:open_api_spec(oaspec@openapi@spec:unresolved())
) -> {ok, oaspec@openapi@spec:open_api_spec(oaspec@openapi@spec:resolved())} |
{error, list(oaspec@openapi@diagnostic:diagnostic())}.
resolve(Spec) ->
gleam@result:'try'(
resolve_internal(Spec),
fun(Resolved) -> {ok, gleam_stdlib:identity(Resolved)} end
).