Packages
oaspec
0.13.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@config.erl
-module(oaspec@config).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/oaspec/config.gleam").
-export([new/6, input/1, output_server/1, output_client/1, package/1, mode/1, validate/1, parse_mode/1, with_mode/2, with_validate/2, with_output/2, validate_output_package_match/1, error_to_string/1, load/1]).
-export_type([config/0, generate_mode/0, config_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.
-opaque config() :: {config,
binary(),
binary(),
binary(),
binary(),
generate_mode(),
boolean()}.
-type generate_mode() :: server | client | both.
-type config_error() :: {file_not_found, binary()} |
{file_read_error, binary(), binary()} |
{parse_error, binary()} |
{missing_field, binary()} |
{invalid_value, binary(), binary()}.
-file("src/oaspec/config.gleam", 28).
?DOC(
" Construct a new `Config` from its six fields. Prefer `load/1` in\n"
" production code; `new/6` is primarily for tests and ad-hoc tooling\n"
" that assembles a config in memory.\n"
).
-spec new(binary(), binary(), binary(), binary(), generate_mode(), boolean()) -> config().
new(Input, Output_server, Output_client, Package, Mode, Validate) ->
{config, Input, Output_server, Output_client, Package, Mode, Validate}.
-file("src/oaspec/config.gleam", 40).
?DOC(" Path to the OpenAPI spec this config was built for.\n").
-spec input(config()) -> binary().
input(Cfg) ->
erlang:element(2, Cfg).
-file("src/oaspec/config.gleam", 45).
?DOC(" Output directory for server-side generated files.\n").
-spec output_server(config()) -> binary().
output_server(Cfg) ->
erlang:element(3, Cfg).
-file("src/oaspec/config.gleam", 50).
?DOC(" Output directory for client-side generated files.\n").
-spec output_client(config()) -> binary().
output_client(Cfg) ->
erlang:element(4, Cfg).
-file("src/oaspec/config.gleam", 55).
?DOC(" Gleam package name (module prefix) for generated files.\n").
-spec package(config()) -> binary().
package(Cfg) ->
erlang:element(5, Cfg).
-file("src/oaspec/config.gleam", 60).
?DOC(" Generation mode: server, client, or both.\n").
-spec mode(config()) -> generate_mode().
mode(Cfg) ->
erlang:element(6, Cfg).
-file("src/oaspec/config.gleam", 65).
?DOC(" Whether guard-based runtime validation is enabled.\n").
-spec validate(config()) -> boolean().
validate(Cfg) ->
erlang:element(7, Cfg).
-file("src/oaspec/config.gleam", 86).
?DOC(" Parse a mode string into GenerateMode.\n").
-spec parse_mode(binary()) -> {ok, generate_mode()} | {error, config_error()}.
parse_mode(Mode) ->
case Mode of
<<"server"/utf8>> ->
{ok, server};
<<"client"/utf8>> ->
{ok, client};
<<"both"/utf8>> ->
{ok, both};
_ ->
{error,
{invalid_value,
<<"mode"/utf8>>,
<<"must be one of: server, client, both"/utf8>>}}
end.
-file("src/oaspec/config.gleam", 184).
?DOC(" Apply CLI overrides to a config.\n").
-spec with_mode(config(), generate_mode()) -> config().
with_mode(Config, Mode) ->
{config,
erlang:element(2, Config),
erlang:element(3, Config),
erlang:element(4, Config),
erlang:element(5, Config),
Mode,
erlang:element(7, Config)}.
-file("src/oaspec/config.gleam", 189).
?DOC(" Apply validation mode override.\n").
-spec with_validate(config(), boolean()) -> config().
with_validate(Config, Validate) ->
{config,
erlang:element(2, Config),
erlang:element(3, Config),
erlang:element(4, Config),
erlang:element(5, Config),
erlang:element(6, Config),
Validate}.
-file("src/oaspec/config.gleam", 195).
?DOC(
" Apply output base directory override.\n"
" Derives server/client paths as <dir>/<package> and <dir>_client/<package>.\n"
).
-spec with_output(config(), gleam@option:option(binary())) -> config().
with_output(Config, Output) ->
case Output of
{some, Dir} ->
{config,
erlang:element(2, Config),
<<<<Dir/binary, "/"/utf8>>/binary,
(erlang:element(5, Config))/binary>>,
<<<<Dir/binary, "_client/"/utf8>>/binary,
(erlang:element(5, Config))/binary>>,
erlang:element(5, Config),
erlang:element(6, Config),
erlang:element(7, Config)};
none ->
Config
end.
-file("src/oaspec/config.gleam", 247).
?DOC(" Get the basename of a path (last segment after /).\n").
-spec basename(binary()) -> binary().
basename(Path) ->
_pipe = Path,
_pipe@1 = gleam@string:split(_pipe, <<"/"/utf8>>),
_pipe@2 = gleam@list:last(_pipe@1),
gleam@result:unwrap(_pipe@2, <<""/utf8>>).
-file("src/oaspec/config.gleam", 209).
?DOC(
" Validate that output directory basenames match the package name.\n"
" Gleam imports require `import <package>/types`, so the directory must match.\n"
).
-spec validate_output_package_match(config()) -> {ok, nil} |
{error, config_error()}.
validate_output_package_match(Config) ->
_pipe = case erlang:element(6, Config) of
server ->
case basename(erlang:element(3, Config)) =:= erlang:element(
5,
Config
) of
true ->
{ok, nil};
false ->
{error,
{invalid_value,
<<"output.server"/utf8>>,
<<<<<<<<"Directory basename '"/utf8,
(basename(erlang:element(3, Config)))/binary>>/binary,
"' must match package '"/utf8>>/binary,
(erlang:element(5, Config))/binary>>/binary,
"'"/utf8>>}}
end;
both ->
case basename(erlang:element(3, Config)) =:= erlang:element(
5,
Config
) of
true ->
{ok, nil};
false ->
{error,
{invalid_value,
<<"output.server"/utf8>>,
<<<<<<<<"Directory basename '"/utf8,
(basename(erlang:element(3, Config)))/binary>>/binary,
"' must match package '"/utf8>>/binary,
(erlang:element(5, Config))/binary>>/binary,
"'"/utf8>>}}
end;
client ->
{ok, nil}
end,
gleam@result:'try'(_pipe, fun(_) -> case erlang:element(6, Config) of
client ->
case basename(erlang:element(4, Config)) =:= erlang:element(
5,
Config
) of
true ->
{ok, nil};
false ->
{error,
{invalid_value,
<<"output.client"/utf8>>,
<<<<<<<<"Directory basename '"/utf8,
(basename(
erlang:element(
4,
Config
)
))/binary>>/binary,
"' must match package '"/utf8>>/binary,
(erlang:element(5, Config))/binary>>/binary,
"'"/utf8>>}}
end;
both ->
case basename(erlang:element(4, Config)) =:= erlang:element(
5,
Config
) of
true ->
{ok, nil};
false ->
{error,
{invalid_value,
<<"output.client"/utf8>>,
<<<<<<<<"Directory basename '"/utf8,
(basename(
erlang:element(
4,
Config
)
))/binary>>/binary,
"' must match package '"/utf8>>/binary,
(erlang:element(5, Config))/binary>>/binary,
"'"/utf8>>}}
end;
server ->
{ok, nil}
end end).
-file("src/oaspec/config.gleam", 255).
?DOC(" Convert config error to a human-readable string.\n").
-spec error_to_string(config_error()) -> binary().
error_to_string(Error) ->
case Error of
{file_not_found, Path} ->
<<"Config file not found: "/utf8, Path/binary>>;
{file_read_error, Path@1, Detail} ->
<<<<<<"Error reading config file "/utf8, Path@1/binary>>/binary,
": "/utf8>>/binary,
Detail/binary>>;
{parse_error, Detail@1} ->
<<"Config parse error: "/utf8, Detail@1/binary>>;
{missing_field, Field} ->
<<"Missing required config field: "/utf8, Field/binary>>;
{invalid_value, Field@1, Detail@2} ->
<<<<<<"Invalid value for "/utf8, Field@1/binary>>/binary,
": "/utf8>>/binary,
Detail@2/binary>>
end.
-file("src/oaspec/config.gleam", 268).
?DOC(" Extract a nested string value from YAML like output.server.\n").
-spec extract_nested_string(yay:node_(), binary(), binary()) -> gleam@option:option(binary()).
extract_nested_string(Root, Key1, Key2) ->
case yay:select_sugar(
Root,
<<<<Key1/binary, "."/utf8>>/binary, Key2/binary>>
) of
{ok, {node_str, Value}} ->
{some, Value};
_ ->
none
end.
-file("src/oaspec/config.gleam", 280).
?DOC(" Convert a yay YAML error to string.\n").
-spec yaml_error_to_string(yay:yaml_error()) -> binary().
yaml_error_to_string(Error) ->
case Error of
unexpected_parsing_error ->
<<"Unexpected parsing error"/utf8>>;
{parsing_error, Msg, _} ->
Msg
end.
-file("src/oaspec/config.gleam", 100).
?DOC(" Load config from a YAML file.\n").
-spec load(binary()) -> {ok, config()} | {error, config_error()}.
load(Path) ->
gleam@result:'try'(
begin
_pipe = simplifile:read(Path),
gleam@result:map_error(_pipe, fun(E) -> case E of
enoent ->
{file_not_found, Path};
_ ->
{file_read_error,
Path,
<<"Failed to read file: "/utf8,
(simplifile:describe_error(E))/binary>>}
end end)
end,
fun(Content) ->
gleam@result:'try'(
begin
_pipe@1 = yaml_ffi:parse_string(Content),
gleam@result:map_error(
_pipe@1,
fun(E@1) ->
{parse_error,
<<"YAML parse error: "/utf8,
(yaml_error_to_string(E@1))/binary>>}
end
)
end,
fun(Docs) -> gleam@result:'try'(case Docs of
[First | _] ->
{ok, First};
[] ->
{error,
{parse_error,
<<"Empty YAML document"/utf8>>}}
end, fun(Doc) ->
Root = yay:document_root(Doc),
gleam@result:'try'(
begin
_pipe@2 = yay:extract_string(
Root,
<<"input"/utf8>>
),
gleam@result:map_error(
_pipe@2,
fun(_) ->
{missing_field, <<"input"/utf8>>}
end
)
end,
fun(Input) ->
Package = begin
_pipe@3 = yay:extract_optional_string(
Root,
<<"package"/utf8>>
),
_pipe@4 = gleam@result:unwrap(
_pipe@3,
none
),
gleam@option:unwrap(
_pipe@4,
<<"api"/utf8>>
)
end,
Output_dir = begin
_pipe@5 = extract_nested_string(
Root,
<<"output"/utf8>>,
<<"dir"/utf8>>
),
gleam@option:unwrap(
_pipe@5,
<<"./gen"/utf8>>
)
end,
Output_server = begin
_pipe@6 = extract_nested_string(
Root,
<<"output"/utf8>>,
<<"server"/utf8>>
),
gleam@option:unwrap(
_pipe@6,
<<<<Output_dir/binary, "/"/utf8>>/binary,
Package/binary>>
)
end,
Output_client = begin
_pipe@7 = extract_nested_string(
Root,
<<"output"/utf8>>,
<<"client"/utf8>>
),
gleam@option:unwrap(
_pipe@7,
<<<<Output_dir/binary,
"_client/"/utf8>>/binary,
Package/binary>>
)
end,
gleam@result:'try'(
case begin
_pipe@8 = yay:extract_optional_string(
Root,
<<"mode"/utf8>>
),
gleam@result:unwrap(_pipe@8, none)
end of
{some, <<"server"/utf8>>} ->
{ok, server};
{some, <<"client"/utf8>>} ->
{ok, client};
{some, <<"both"/utf8>>} ->
{ok, both};
none ->
{ok, both};
{some, Other} ->
{error,
{invalid_value,
<<"mode"/utf8>>,
<<<<"must be one of: server, client, both (got: "/utf8,
Other/binary>>/binary,
")"/utf8>>}}
end,
fun(Mode) ->
gleam@result:'try'(
case yay:select_sugar(
Root,
<<"validate"/utf8>>
) of
{ok, {node_bool, true}} ->
{ok, true};
{ok,
{node_str,
<<"true"/utf8>>}} ->
{ok, true};
{ok, {node_bool, false}} ->
{ok, false};
{ok,
{node_str,
<<"false"/utf8>>}} ->
{ok, false};
{error, _} ->
{ok, false};
{ok, _} ->
{error,
{invalid_value,
<<"validate"/utf8>>,
<<"must be a boolean (true or false)"/utf8>>}}
end,
fun(Validate) ->
{ok,
{config,
Input,
Output_server,
Output_client,
Package,
Mode,
Validate}}
end
)
end
)
end
)
end) end
)
end
).