-module(oaisp@endpoint).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/oaisp/endpoint.gleam").
-export([get/1, post/1, put/1, patch/1, delete/1, with_body/2, with_response/3, with_empty_response/3, with_path_param/3, with_query_param/4, with_query_record/2, with_summary/2, with_description/2, with_tag/2, with_operation_id/2, method/1, path/1, summary/1, description/1, operation_id/1, tags/1, path_params/1, query_params/1, query_record/1, body/1, responses/1, method_to_string/1, type_refs/1, placeholder_name/1, to_json/1, decoder/0]).
-export_type([method/0, param/0, response/0, endpoint/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.
?MODULEDOC(
" Endpoint declarations: typed values capturing an operation's method, path,\n"
" parameters, request body, and responses.\n"
"\n"
" Each declaration fuses a route with the codecs its handler uses, so the\n"
" emitted document and the runtime contract are read from one place. An\n"
" `Endpoint` is built with a method constructor ([`get`](#get),\n"
" [`post`](#post), …) and refined with the `with_*` combinators; it is opaque\n"
" so it can never exist without a method and a path.\n"
).
-type method() :: get | post | put | patch | delete.
-type param() :: {param, binary(), oaisp@schema:schema(), boolean()}.
-type response() :: {response,
integer(),
gleam@option:option(oaisp@schema:schema()),
gleam@option:option(binary())}.
-opaque endpoint() :: {endpoint,
method(),
binary(),
gleam@option:option(binary()),
gleam@option:option(binary()),
gleam@option:option(binary()),
list(binary()),
list(param()),
list(param()),
gleam@option:option(oaisp@schema:schema()),
gleam@option:option(oaisp@schema:schema()),
list(response())}.
-file("src/oaisp/endpoint.gleam", 58).
-spec new(method(), binary()) -> endpoint().
new(Method, Path) ->
{endpoint, Method, Path, none, none, none, [], [], [], none, none, []}.
-file("src/oaisp/endpoint.gleam", 75).
?DOC(" A `GET` endpoint at `path`.\n").
-spec get(binary()) -> endpoint().
get(Path) ->
new(get, Path).
-file("src/oaisp/endpoint.gleam", 80).
?DOC(" A `POST` endpoint at `path`.\n").
-spec post(binary()) -> endpoint().
post(Path) ->
new(post, Path).
-file("src/oaisp/endpoint.gleam", 85).
?DOC(" A `PUT` endpoint at `path`.\n").
-spec put(binary()) -> endpoint().
put(Path) ->
new(put, Path).
-file("src/oaisp/endpoint.gleam", 90).
?DOC(" A `PATCH` endpoint at `path`.\n").
-spec patch(binary()) -> endpoint().
patch(Path) ->
new(patch, Path).
-file("src/oaisp/endpoint.gleam", 95).
?DOC(" A `DELETE` endpoint at `path`.\n").
-spec delete(binary()) -> endpoint().
delete(Path) ->
new(delete, Path).
-file("src/oaisp/endpoint.gleam", 100).
?DOC(" Attach a request-body schema, taken from `codec`.\n").
-spec with_body(endpoint(), oaisp@schema:schema()) -> endpoint().
with_body(Endpoint, Schema) ->
{endpoint,
erlang:element(2, Endpoint),
erlang:element(3, Endpoint),
erlang:element(4, Endpoint),
erlang:element(5, Endpoint),
erlang:element(6, Endpoint),
erlang:element(7, Endpoint),
erlang:element(8, Endpoint),
erlang:element(9, Endpoint),
erlang:element(10, Endpoint),
{some, Schema},
erlang:element(12, Endpoint)}.
-file("src/oaisp/endpoint.gleam", 105).
?DOC(" Document a response with a body schema for `status`.\n").
-spec with_response(endpoint(), integer(), oaisp@schema:schema()) -> endpoint().
with_response(Endpoint, Status, Schema) ->
Response = {response, Status, {some, Schema}, none},
{endpoint,
erlang:element(2, Endpoint),
erlang:element(3, Endpoint),
erlang:element(4, Endpoint),
erlang:element(5, Endpoint),
erlang:element(6, Endpoint),
erlang:element(7, Endpoint),
erlang:element(8, Endpoint),
erlang:element(9, Endpoint),
erlang:element(10, Endpoint),
erlang:element(11, Endpoint),
lists:append(erlang:element(12, Endpoint), [Response])}.
-file("src/oaisp/endpoint.gleam", 115).
?DOC(" Document an empty (bodyless) response for `status`, with a description.\n").
-spec with_empty_response(endpoint(), integer(), binary()) -> endpoint().
with_empty_response(Endpoint, Status, Description) ->
Response = {response, Status, none, {some, Description}},
{endpoint,
erlang:element(2, Endpoint),
erlang:element(3, Endpoint),
erlang:element(4, Endpoint),
erlang:element(5, Endpoint),
erlang:element(6, Endpoint),
erlang:element(7, Endpoint),
erlang:element(8, Endpoint),
erlang:element(9, Endpoint),
erlang:element(10, Endpoint),
erlang:element(11, Endpoint),
lists:append(erlang:element(12, Endpoint), [Response])}.
-file("src/oaisp/endpoint.gleam", 125).
?DOC(" Document a path parameter. Path parameters are always required.\n").
-spec with_path_param(endpoint(), binary(), oaisp@schema:schema()) -> endpoint().
with_path_param(Endpoint, Name, Schema) ->
Param = {param, Name, Schema, true},
{endpoint,
erlang:element(2, Endpoint),
erlang:element(3, Endpoint),
erlang:element(4, Endpoint),
erlang:element(5, Endpoint),
erlang:element(6, Endpoint),
erlang:element(7, Endpoint),
lists:append(erlang:element(8, Endpoint), [Param]),
erlang:element(9, Endpoint),
erlang:element(10, Endpoint),
erlang:element(11, Endpoint),
erlang:element(12, Endpoint)}.
-file("src/oaisp/endpoint.gleam", 135).
?DOC(" Document a query parameter, marking whether it is required.\n").
-spec with_query_param(endpoint(), binary(), oaisp@schema:schema(), boolean()) -> endpoint().
with_query_param(Endpoint, Name, Schema, Required) ->
Param = {param, Name, Schema, Required},
{endpoint,
erlang:element(2, Endpoint),
erlang:element(3, Endpoint),
erlang:element(4, Endpoint),
erlang:element(5, Endpoint),
erlang:element(6, Endpoint),
erlang:element(7, Endpoint),
erlang:element(8, Endpoint),
lists:append(erlang:element(9, Endpoint), [Param]),
erlang:element(10, Endpoint),
erlang:element(11, Endpoint),
erlang:element(12, Endpoint)}.
-file("src/oaisp/endpoint.gleam", 153).
?DOC(
" Document query parameters by reference to a record type: each of the\n"
" record's scalar fields becomes a query parameter (an `Option` field is\n"
" optional, the rest required). The type is resolved at merge time from the\n"
" package interface; fields oaisp can't express as a scalar query parameter\n"
" are soundly omitted. Mirrors F#'s `addQueryParameters<'T>`.\n"
).
-spec with_query_record(endpoint(), oaisp@schema:schema()) -> endpoint().
with_query_record(Endpoint, Schema) ->
{endpoint,
erlang:element(2, Endpoint),
erlang:element(3, Endpoint),
erlang:element(4, Endpoint),
erlang:element(5, Endpoint),
erlang:element(6, Endpoint),
erlang:element(7, Endpoint),
erlang:element(8, Endpoint),
erlang:element(9, Endpoint),
{some, Schema},
erlang:element(11, Endpoint),
erlang:element(12, Endpoint)}.
-file("src/oaisp/endpoint.gleam", 158).
?DOC(" Set the operation summary (a short one-line label).\n").
-spec with_summary(endpoint(), binary()) -> endpoint().
with_summary(Endpoint, Summary) ->
{endpoint,
erlang:element(2, Endpoint),
erlang:element(3, Endpoint),
{some, Summary},
erlang:element(5, Endpoint),
erlang:element(6, Endpoint),
erlang:element(7, Endpoint),
erlang:element(8, Endpoint),
erlang:element(9, Endpoint),
erlang:element(10, Endpoint),
erlang:element(11, Endpoint),
erlang:element(12, Endpoint)}.
-file("src/oaisp/endpoint.gleam", 163).
?DOC(" Set the operation description (longer prose).\n").
-spec with_description(endpoint(), binary()) -> endpoint().
with_description(Endpoint, Description) ->
{endpoint,
erlang:element(2, Endpoint),
erlang:element(3, Endpoint),
erlang:element(4, Endpoint),
{some, Description},
erlang:element(6, Endpoint),
erlang:element(7, Endpoint),
erlang:element(8, Endpoint),
erlang:element(9, Endpoint),
erlang:element(10, Endpoint),
erlang:element(11, Endpoint),
erlang:element(12, Endpoint)}.
-file("src/oaisp/endpoint.gleam", 168).
?DOC(" Add a tag, used to group operations in the document.\n").
-spec with_tag(endpoint(), binary()) -> endpoint().
with_tag(Endpoint, Tag) ->
{endpoint,
erlang:element(2, Endpoint),
erlang:element(3, Endpoint),
erlang:element(4, Endpoint),
erlang:element(5, Endpoint),
erlang:element(6, Endpoint),
lists:append(erlang:element(7, Endpoint), [Tag]),
erlang:element(8, Endpoint),
erlang:element(9, Endpoint),
erlang:element(10, Endpoint),
erlang:element(11, Endpoint),
erlang:element(12, Endpoint)}.
-file("src/oaisp/endpoint.gleam", 173).
?DOC(" Set the `operationId`, a unique identifier for the operation.\n").
-spec with_operation_id(endpoint(), binary()) -> endpoint().
with_operation_id(Endpoint, Id) ->
{endpoint,
erlang:element(2, Endpoint),
erlang:element(3, Endpoint),
erlang:element(4, Endpoint),
erlang:element(5, Endpoint),
{some, Id},
erlang:element(7, Endpoint),
erlang:element(8, Endpoint),
erlang:element(9, Endpoint),
erlang:element(10, Endpoint),
erlang:element(11, Endpoint),
erlang:element(12, Endpoint)}.
-file("src/oaisp/endpoint.gleam", 178).
?DOC(" The endpoint's HTTP method.\n").
-spec method(endpoint()) -> method().
method(Endpoint) ->
erlang:element(2, Endpoint).
-file("src/oaisp/endpoint.gleam", 183).
?DOC(" The endpoint's path, including any `{param}` placeholders.\n").
-spec path(endpoint()) -> binary().
path(Endpoint) ->
erlang:element(3, Endpoint).
-file("src/oaisp/endpoint.gleam", 188).
?DOC(" The endpoint's summary, if set.\n").
-spec summary(endpoint()) -> gleam@option:option(binary()).
summary(Endpoint) ->
erlang:element(4, Endpoint).
-file("src/oaisp/endpoint.gleam", 193).
?DOC(" The endpoint's description, if set.\n").
-spec description(endpoint()) -> gleam@option:option(binary()).
description(Endpoint) ->
erlang:element(5, Endpoint).
-file("src/oaisp/endpoint.gleam", 198).
?DOC(" The endpoint's `operationId`, if set.\n").
-spec operation_id(endpoint()) -> gleam@option:option(binary()).
operation_id(Endpoint) ->
erlang:element(6, Endpoint).
-file("src/oaisp/endpoint.gleam", 203).
?DOC(" The endpoint's tags, in declaration order.\n").
-spec tags(endpoint()) -> list(binary()).
tags(Endpoint) ->
erlang:element(7, Endpoint).
-file("src/oaisp/endpoint.gleam", 208).
?DOC(" The endpoint's path parameters, in declaration order.\n").
-spec path_params(endpoint()) -> list(param()).
path_params(Endpoint) ->
erlang:element(8, Endpoint).
-file("src/oaisp/endpoint.gleam", 213).
?DOC(" The endpoint's query parameters, in declaration order.\n").
-spec query_params(endpoint()) -> list(param()).
query_params(Endpoint) ->
erlang:element(9, Endpoint).
-file("src/oaisp/endpoint.gleam", 219).
?DOC(
" The record type whose scalar fields are reflected into query parameters, if\n"
" one was set with [`with_query_record`](#with_query_record).\n"
).
-spec query_record(endpoint()) -> gleam@option:option(oaisp@schema:schema()).
query_record(Endpoint) ->
erlang:element(10, Endpoint).
-file("src/oaisp/endpoint.gleam", 224).
?DOC(" The endpoint's request-body schema, if any.\n").
-spec body(endpoint()) -> gleam@option:option(oaisp@schema:schema()).
body(Endpoint) ->
erlang:element(11, Endpoint).
-file("src/oaisp/endpoint.gleam", 229).
?DOC(" The endpoint's documented responses, in declaration order.\n").
-spec responses(endpoint()) -> list(response()).
responses(Endpoint) ->
erlang:element(12, Endpoint).
-file("src/oaisp/endpoint.gleam", 234).
?DOC(" The string used for `method` in an OpenAPI path item (lower-cased).\n").
-spec method_to_string(method()) -> binary().
method_to_string(Method) ->
case Method of
get ->
<<"get"/utf8>>;
post ->
<<"post"/utf8>>;
put ->
<<"put"/utf8>>;
patch ->
<<"patch"/utf8>>;
delete ->
<<"delete"/utf8>>
end.
-file("src/oaisp/endpoint.gleam", 249).
?DOC(false).
-spec type_refs(endpoint()) -> list({binary(), binary()}).
type_refs(Endpoint) ->
Bodies = [erlang:element(11, Endpoint) |
gleam@list:map(
erlang:element(12, Endpoint),
fun(R) -> erlang:element(3, R) end
)],
Params = lists:append(
erlang:element(8, Endpoint),
erlang:element(9, Endpoint)
),
_pipe = lists:append(
gleam@option:values(Bodies),
gleam@list:map(Params, fun(P) -> erlang:element(3, P) end)
),
_pipe@1 = gleam@list:filter_map(_pipe, fun oaisp@schema:type_ref_parts/1),
gleam@list:unique(_pipe@1).
-file("src/oaisp/endpoint.gleam", 261).
?DOC(false).
-spec placeholder_name(binary()) -> gleam@option:option(binary()).
placeholder_name(Segment) ->
case gleam_stdlib:string_starts_with(Segment, <<"{"/utf8>>) andalso gleam_stdlib:string_ends_with(
Segment,
<<"}"/utf8>>
) of
true ->
{some,
begin
_pipe = Segment,
_pipe@1 = gleam@string:drop_start(_pipe, 1),
gleam@string:drop_end(_pipe@1, 1)
end};
false ->
none
end.
-file("src/oaisp/endpoint.gleam", 270).
-spec method_from_string(binary()) -> {ok, method()} | {error, nil}.
method_from_string(Name) ->
case Name of
<<"get"/utf8>> ->
{ok, get};
<<"post"/utf8>> ->
{ok, post};
<<"put"/utf8>> ->
{ok, put};
<<"patch"/utf8>> ->
{ok, patch};
<<"delete"/utf8>> ->
{ok, delete};
_ ->
{error, nil}
end.
-file("src/oaisp/endpoint.gleam", 281).
-spec method_decoder() -> gleam@dynamic@decode:decoder(method()).
method_decoder() ->
gleam@dynamic@decode:then(
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Raw) -> case method_from_string(Raw) of
{ok, Method} ->
gleam@dynamic@decode:success(Method);
{error, nil} ->
gleam@dynamic@decode:failure(get, <<"Method"/utf8>>)
end end
).
-file("src/oaisp/endpoint.gleam", 289).
-spec param_to_json(param()) -> gleam@json:json().
param_to_json(Param) ->
gleam@json:object(
[{<<"name"/utf8>>, gleam@json:string(erlang:element(2, Param))},
{<<"required"/utf8>>, gleam@json:bool(erlang:element(4, Param))},
{<<"schema"/utf8>>,
oaisp@schema:schema_to_json(erlang:element(3, Param))}]
).
-file("src/oaisp/endpoint.gleam", 297).
-spec param_decoder() -> gleam@dynamic@decode:decoder(param()).
param_decoder() ->
gleam@dynamic@decode:field(
<<"name"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Name) ->
gleam@dynamic@decode:field(
<<"required"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_bool/1},
fun(Required) ->
gleam@dynamic@decode:field(
<<"schema"/utf8>>,
oaisp@schema:schema_decoder(),
fun(Param_schema) ->
gleam@dynamic@decode:success(
{param, Name, Param_schema, Required}
)
end
)
end
)
end
).
-file("src/oaisp/endpoint.gleam", 304).
-spec response_to_json(response()) -> gleam@json:json().
response_to_json(Response) ->
gleam@json:object(
[{<<"status"/utf8>>, gleam@json:int(erlang:element(2, Response))},
{<<"body"/utf8>>,
gleam@json:nullable(
erlang:element(3, Response),
fun oaisp@schema:schema_to_json/1
)},
{<<"description"/utf8>>,
gleam@json:nullable(
erlang:element(4, Response),
fun gleam@json:string/1
)}]
).
-file("src/oaisp/endpoint.gleam", 312).
-spec response_decoder() -> gleam@dynamic@decode:decoder(response()).
response_decoder() ->
gleam@dynamic@decode:field(
<<"status"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1},
fun(Status) ->
gleam@dynamic@decode:field(
<<"body"/utf8>>,
gleam@dynamic@decode:optional(oaisp@schema:schema_decoder()),
fun(Body) ->
gleam@dynamic@decode:field(
<<"description"/utf8>>,
gleam@dynamic@decode:optional(
{decoder, fun gleam@dynamic@decode:decode_string/1}
),
fun(Description) ->
gleam@dynamic@decode:success(
{response, Status, Body, Description}
)
end
)
end
)
end
).
-file("src/oaisp/endpoint.gleam", 321).
?DOC(false).
-spec to_json(endpoint()) -> gleam@json:json().
to_json(Endpoint) ->
gleam@json:object(
[{<<"method"/utf8>>,
gleam@json:string(method_to_string(erlang:element(2, Endpoint)))},
{<<"path"/utf8>>, gleam@json:string(erlang:element(3, Endpoint))},
{<<"summary"/utf8>>,
gleam@json:nullable(
erlang:element(4, Endpoint),
fun gleam@json:string/1
)},
{<<"description"/utf8>>,
gleam@json:nullable(
erlang:element(5, Endpoint),
fun gleam@json:string/1
)},
{<<"operation_id"/utf8>>,
gleam@json:nullable(
erlang:element(6, Endpoint),
fun gleam@json:string/1
)},
{<<"tags"/utf8>>,
gleam@json:array(
erlang:element(7, Endpoint),
fun gleam@json:string/1
)},
{<<"path_params"/utf8>>,
gleam@json:array(
erlang:element(8, Endpoint),
fun param_to_json/1
)},
{<<"query_params"/utf8>>,
gleam@json:array(
erlang:element(9, Endpoint),
fun param_to_json/1
)},
{<<"query_record"/utf8>>,
gleam@json:nullable(
erlang:element(10, Endpoint),
fun oaisp@schema:schema_to_json/1
)},
{<<"body"/utf8>>,
gleam@json:nullable(
erlang:element(11, Endpoint),
fun oaisp@schema:schema_to_json/1
)},
{<<"responses"/utf8>>,
gleam@json:array(
erlang:element(12, Endpoint),
fun response_to_json/1
)}]
).
-file("src/oaisp/endpoint.gleam", 340).
?DOC(false).
-spec decoder() -> gleam@dynamic@decode:decoder(endpoint()).
decoder() ->
gleam@dynamic@decode:field(
<<"method"/utf8>>,
method_decoder(),
fun(Method) ->
gleam@dynamic@decode:field(
<<"path"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Path) ->
gleam@dynamic@decode:field(
<<"summary"/utf8>>,
gleam@dynamic@decode:optional(
{decoder, fun gleam@dynamic@decode:decode_string/1}
),
fun(Summary) ->
gleam@dynamic@decode:field(
<<"description"/utf8>>,
gleam@dynamic@decode:optional(
{decoder,
fun gleam@dynamic@decode:decode_string/1}
),
fun(Description) ->
gleam@dynamic@decode:field(
<<"operation_id"/utf8>>,
gleam@dynamic@decode:optional(
{decoder,
fun gleam@dynamic@decode:decode_string/1}
),
fun(Operation_id) ->
gleam@dynamic@decode:field(
<<"tags"/utf8>>,
gleam@dynamic@decode:list(
{decoder,
fun gleam@dynamic@decode:decode_string/1}
),
fun(Tags) ->
gleam@dynamic@decode:field(
<<"path_params"/utf8>>,
gleam@dynamic@decode:list(
param_decoder()
),
fun(Path_params) ->
gleam@dynamic@decode:field(
<<"query_params"/utf8>>,
gleam@dynamic@decode:list(
param_decoder(
)
),
fun(
Query_params
) ->
gleam@dynamic@decode:field(
<<"query_record"/utf8>>,
gleam@dynamic@decode:optional(
oaisp@schema:schema_decoder(
)
),
fun(
Query_record
) ->
gleam@dynamic@decode:field(
<<"body"/utf8>>,
gleam@dynamic@decode:optional(
oaisp@schema:schema_decoder(
)
),
fun(
Body
) ->
gleam@dynamic@decode:field(
<<"responses"/utf8>>,
gleam@dynamic@decode:list(
response_decoder(
)
),
fun(
Responses
) ->
gleam@dynamic@decode:success(
{endpoint,
Method,
Path,
Summary,
Description,
Operation_id,
Tags,
Path_params,
Query_params,
Query_record,
Body,
Responses}
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
).