mirror of
https://github.com/jlengrand/openapi-generator.git
synced 2026-05-17 08:31:23 +00:00
commit c5a0d0f7394aa742fa336fff7e7c1d3049761868
Merge: 8c4991ba3e f8ff8c87609
Author: William Cheng <wing328hk@gmail.com>
Date: Tue Aug 17 18:28:12 2021 +0800
Merge branch 'mustache-linting' of https://github.com/NathanBaulch/openapi-generator into NathanBaulch-mustache-linting
commit f8ff8c87609b1ca36fa26fb8474806999638195e
Author: Nathan Baulch <nathan.baulch@gmail.com>
Date: Thu Aug 5 14:12:47 2021 +1000
Reorder tags that handle missing values
commit f5d8a33709d6a3f846a9fe4520b78c3d637051d9
Author: Nathan Baulch <nathan.baulch@gmail.com>
Date: Thu Aug 5 14:08:59 2021 +1000
Use dot notation where possible
commit 493d14921e2333f3ae19ef6fc89318b7e263a80c
Author: Nathan Baulch <nathan.baulch@gmail.com>
Date: Thu Aug 5 14:10:49 2021 +1000
Remove empty tags
commit 32480dc53f48227d55531b94e307d72671373737
Author: Nathan Baulch <nathan.baulch@gmail.com>
Date: Thu Aug 5 10:41:58 2021 +1000
Remove redundant sections
commit a8edabd722c34aa094b4aeb11c22664529c3a219
Author: Nathan Baulch <nathan.baulch@gmail.com>
Date: Wed Aug 4 22:02:22 2021 +1000
Trim extra EOF new lines
commit e89bd7458e3594bf0d30e580bc9408e45b018a57
Author: Nathan Baulch <nathan.baulch@gmail.com>
Date: Wed Aug 4 21:59:26 2021 +1000
Trim trailing whitespace
757 lines
20 KiB
Erlang
757 lines
20 KiB
Erlang
-module(openapi_api).
|
|
|
|
-export([request_params/1]).
|
|
-export([request_param_info/2]).
|
|
-export([populate_request/3]).
|
|
-export([validate_response/4]).
|
|
%% exported to silence openapi complains
|
|
-export([get_value/3, validate_response_body/4]).
|
|
|
|
-type operation_id() :: atom().
|
|
-type request_param() :: atom().
|
|
|
|
-export_type([operation_id/0]).
|
|
|
|
-spec request_params(OperationID :: operation_id()) -> [Param :: request_param()].
|
|
|
|
|
|
request_params('AddPet') ->
|
|
[
|
|
'Pet'
|
|
];
|
|
|
|
request_params('DeletePet') ->
|
|
[
|
|
'petId',
|
|
'api_key'
|
|
];
|
|
|
|
request_params('FindPetsByStatus') ->
|
|
[
|
|
'status'
|
|
];
|
|
|
|
request_params('FindPetsByTags') ->
|
|
[
|
|
'tags'
|
|
];
|
|
|
|
request_params('GetPetById') ->
|
|
[
|
|
'petId'
|
|
];
|
|
|
|
request_params('UpdatePet') ->
|
|
[
|
|
'Pet'
|
|
];
|
|
|
|
request_params('UpdatePetWithForm') ->
|
|
[
|
|
'petId',
|
|
'name',
|
|
'status'
|
|
];
|
|
|
|
request_params('UploadFile') ->
|
|
[
|
|
'petId',
|
|
'additionalMetadata',
|
|
'file'
|
|
];
|
|
|
|
|
|
request_params('DeleteOrder') ->
|
|
[
|
|
'orderId'
|
|
];
|
|
|
|
request_params('GetInventory') ->
|
|
[
|
|
];
|
|
|
|
request_params('GetOrderById') ->
|
|
[
|
|
'orderId'
|
|
];
|
|
|
|
request_params('PlaceOrder') ->
|
|
[
|
|
'Order'
|
|
];
|
|
|
|
|
|
request_params('CreateUser') ->
|
|
[
|
|
'User'
|
|
];
|
|
|
|
request_params('CreateUsersWithArrayInput') ->
|
|
[
|
|
'list'
|
|
];
|
|
|
|
request_params('CreateUsersWithListInput') ->
|
|
[
|
|
'list'
|
|
];
|
|
|
|
request_params('DeleteUser') ->
|
|
[
|
|
'username'
|
|
];
|
|
|
|
request_params('GetUserByName') ->
|
|
[
|
|
'username'
|
|
];
|
|
|
|
request_params('LoginUser') ->
|
|
[
|
|
'username',
|
|
'password'
|
|
];
|
|
|
|
request_params('LogoutUser') ->
|
|
[
|
|
];
|
|
|
|
request_params('UpdateUser') ->
|
|
[
|
|
'username',
|
|
'User'
|
|
];
|
|
|
|
request_params(_) ->
|
|
error(unknown_operation).
|
|
|
|
-type rule() ::
|
|
{type, 'binary'} |
|
|
{type, 'integer'} |
|
|
{type, 'float'} |
|
|
{type, 'binary'} |
|
|
{type, 'boolean'} |
|
|
{type, 'date'} |
|
|
{type, 'datetime'} |
|
|
{enum, [atom()]} |
|
|
{max, Max :: number()} |
|
|
{exclusive_max, Max :: number()} |
|
|
{min, Min :: number()} |
|
|
{exclusive_min, Min :: number()} |
|
|
{max_length, MaxLength :: integer()} |
|
|
{min_length, MaxLength :: integer()} |
|
|
{pattern, Pattern :: string()} |
|
|
schema |
|
|
required |
|
|
not_required.
|
|
|
|
-spec request_param_info(OperationID :: operation_id(), Name :: request_param()) -> #{
|
|
source => qs_val | binding | header | body,
|
|
rules => [rule()]
|
|
}.
|
|
|
|
|
|
|
|
request_param_info('AddPet', 'Pet') ->
|
|
#{
|
|
source => body,
|
|
rules => [
|
|
schema,
|
|
required
|
|
]
|
|
};
|
|
|
|
request_param_info('DeletePet', 'petId') ->
|
|
#{
|
|
source => binding ,
|
|
rules => [
|
|
{type, 'integer'},
|
|
required
|
|
]
|
|
};
|
|
|
|
request_param_info('DeletePet', 'api_key') ->
|
|
#{
|
|
source => header,
|
|
rules => [
|
|
{type, 'binary'},
|
|
not_required
|
|
]
|
|
};
|
|
|
|
request_param_info('FindPetsByStatus', 'status') ->
|
|
#{
|
|
source => qs_val ,
|
|
rules => [
|
|
{enum, ['available', 'pending', 'sold'] },
|
|
required
|
|
]
|
|
};
|
|
|
|
request_param_info('FindPetsByTags', 'tags') ->
|
|
#{
|
|
source => qs_val ,
|
|
rules => [
|
|
required
|
|
]
|
|
};
|
|
|
|
request_param_info('GetPetById', 'petId') ->
|
|
#{
|
|
source => binding ,
|
|
rules => [
|
|
{type, 'integer'},
|
|
required
|
|
]
|
|
};
|
|
|
|
request_param_info('UpdatePet', 'Pet') ->
|
|
#{
|
|
source => body,
|
|
rules => [
|
|
schema,
|
|
required
|
|
]
|
|
};
|
|
|
|
request_param_info('UpdatePetWithForm', 'petId') ->
|
|
#{
|
|
source => binding ,
|
|
rules => [
|
|
{type, 'integer'},
|
|
required
|
|
]
|
|
};
|
|
|
|
request_param_info('UpdatePetWithForm', 'name') ->
|
|
#{
|
|
source => body,
|
|
rules => [
|
|
{type, 'binary'},
|
|
not_required
|
|
]
|
|
};
|
|
|
|
request_param_info('UpdatePetWithForm', 'status') ->
|
|
#{
|
|
source => body,
|
|
rules => [
|
|
{type, 'binary'},
|
|
not_required
|
|
]
|
|
};
|
|
|
|
request_param_info('UploadFile', 'petId') ->
|
|
#{
|
|
source => binding ,
|
|
rules => [
|
|
{type, 'integer'},
|
|
required
|
|
]
|
|
};
|
|
|
|
request_param_info('UploadFile', 'additionalMetadata') ->
|
|
#{
|
|
source => body,
|
|
rules => [
|
|
{type, 'binary'},
|
|
not_required
|
|
]
|
|
};
|
|
|
|
request_param_info('UploadFile', 'file') ->
|
|
#{
|
|
source => body,
|
|
rules => [
|
|
{type, 'binary'},
|
|
not_required
|
|
]
|
|
};
|
|
|
|
|
|
request_param_info('DeleteOrder', 'orderId') ->
|
|
#{
|
|
source => binding ,
|
|
rules => [
|
|
{type, 'binary'},
|
|
required
|
|
]
|
|
};
|
|
|
|
request_param_info('GetOrderById', 'orderId') ->
|
|
#{
|
|
source => binding ,
|
|
rules => [
|
|
{type, 'integer'},
|
|
{max, 5 },
|
|
{min, 1 },
|
|
required
|
|
]
|
|
};
|
|
|
|
request_param_info('PlaceOrder', 'Order') ->
|
|
#{
|
|
source => body,
|
|
rules => [
|
|
schema,
|
|
required
|
|
]
|
|
};
|
|
|
|
|
|
request_param_info('CreateUser', 'User') ->
|
|
#{
|
|
source => body,
|
|
rules => [
|
|
schema,
|
|
required
|
|
]
|
|
};
|
|
|
|
request_param_info('CreateUsersWithArrayInput', 'list') ->
|
|
#{
|
|
source => body,
|
|
rules => [
|
|
schema,
|
|
required
|
|
]
|
|
};
|
|
|
|
request_param_info('CreateUsersWithListInput', 'list') ->
|
|
#{
|
|
source => body,
|
|
rules => [
|
|
schema,
|
|
required
|
|
]
|
|
};
|
|
|
|
request_param_info('DeleteUser', 'username') ->
|
|
#{
|
|
source => binding ,
|
|
rules => [
|
|
{type, 'binary'},
|
|
required
|
|
]
|
|
};
|
|
|
|
request_param_info('GetUserByName', 'username') ->
|
|
#{
|
|
source => binding ,
|
|
rules => [
|
|
{type, 'binary'},
|
|
required
|
|
]
|
|
};
|
|
|
|
request_param_info('LoginUser', 'username') ->
|
|
#{
|
|
source => qs_val ,
|
|
rules => [
|
|
{type, 'binary'},
|
|
{pattern, "^[a-zA-Z0-9]+[a-zA-Z0-9\\.\\-_]*[a-zA-Z0-9]+$" },
|
|
required
|
|
]
|
|
};
|
|
|
|
request_param_info('LoginUser', 'password') ->
|
|
#{
|
|
source => qs_val ,
|
|
rules => [
|
|
{type, 'binary'},
|
|
required
|
|
]
|
|
};
|
|
|
|
request_param_info('UpdateUser', 'username') ->
|
|
#{
|
|
source => binding ,
|
|
rules => [
|
|
{type, 'binary'},
|
|
required
|
|
]
|
|
};
|
|
|
|
request_param_info('UpdateUser', 'User') ->
|
|
#{
|
|
source => body,
|
|
rules => [
|
|
schema,
|
|
required
|
|
]
|
|
};
|
|
|
|
request_param_info(OperationID, Name) ->
|
|
error({unknown_param, OperationID, Name}).
|
|
|
|
-spec populate_request(
|
|
OperationID :: operation_id(),
|
|
Req :: cowboy_req:req(),
|
|
ValidatorState :: jesse_state:state()
|
|
) ->
|
|
{ok, Model :: #{}, Req :: cowboy_req:req()} |
|
|
{error, Reason :: any(), Req :: cowboy_req:req()}.
|
|
|
|
populate_request(OperationID, Req, ValidatorState) ->
|
|
Params = request_params(OperationID),
|
|
populate_request_params(OperationID, Params, Req, ValidatorState, #{}).
|
|
|
|
populate_request_params(_, [], Req, _, Model) ->
|
|
{ok, Model, Req};
|
|
|
|
populate_request_params(OperationID, [FieldParams | T], Req0, ValidatorState, Model) ->
|
|
case populate_request_param(OperationID, FieldParams, Req0, ValidatorState) of
|
|
{ok, K, V, Req} ->
|
|
populate_request_params(OperationID, T, Req, ValidatorState, maps:put(K, V, Model));
|
|
Error ->
|
|
Error
|
|
end.
|
|
|
|
populate_request_param(OperationID, Name, Req0, ValidatorState) ->
|
|
#{rules := Rules, source := Source} = request_param_info(OperationID, Name),
|
|
case get_value(Source, Name, Req0) of
|
|
{error, Reason, Req} ->
|
|
{error, Reason, Req};
|
|
{Value, Req} ->
|
|
case prepare_param(Rules, Name, Value, ValidatorState) of
|
|
{ok, Result} -> {ok, Name, Result, Req};
|
|
{error, Reason} ->
|
|
{error, Reason, Req}
|
|
end
|
|
end.
|
|
|
|
-spec validate_response(
|
|
OperationID :: operation_id(),
|
|
Code :: 200..599,
|
|
Body :: jesse:json_term(),
|
|
ValidatorState :: jesse_state:state()
|
|
) -> ok | no_return().
|
|
|
|
|
|
validate_response('AddPet', 200, Body, ValidatorState) ->
|
|
validate_response_body('Pet', 'Pet', Body, ValidatorState);
|
|
validate_response('AddPet', 405, Body, ValidatorState) ->
|
|
validate_response_body('', '', Body, ValidatorState);
|
|
|
|
validate_response('DeletePet', 400, Body, ValidatorState) ->
|
|
validate_response_body('', '', Body, ValidatorState);
|
|
|
|
validate_response('FindPetsByStatus', 200, Body, ValidatorState) ->
|
|
validate_response_body('list', 'Pet', Body, ValidatorState);
|
|
validate_response('FindPetsByStatus', 400, Body, ValidatorState) ->
|
|
validate_response_body('', '', Body, ValidatorState);
|
|
|
|
validate_response('FindPetsByTags', 200, Body, ValidatorState) ->
|
|
validate_response_body('list', 'Pet', Body, ValidatorState);
|
|
validate_response('FindPetsByTags', 400, Body, ValidatorState) ->
|
|
validate_response_body('', '', Body, ValidatorState);
|
|
|
|
validate_response('GetPetById', 200, Body, ValidatorState) ->
|
|
validate_response_body('Pet', 'Pet', Body, ValidatorState);
|
|
validate_response('GetPetById', 400, Body, ValidatorState) ->
|
|
validate_response_body('', '', Body, ValidatorState);
|
|
validate_response('GetPetById', 404, Body, ValidatorState) ->
|
|
validate_response_body('', '', Body, ValidatorState);
|
|
|
|
validate_response('UpdatePet', 200, Body, ValidatorState) ->
|
|
validate_response_body('Pet', 'Pet', Body, ValidatorState);
|
|
validate_response('UpdatePet', 400, Body, ValidatorState) ->
|
|
validate_response_body('', '', Body, ValidatorState);
|
|
validate_response('UpdatePet', 404, Body, ValidatorState) ->
|
|
validate_response_body('', '', Body, ValidatorState);
|
|
validate_response('UpdatePet', 405, Body, ValidatorState) ->
|
|
validate_response_body('', '', Body, ValidatorState);
|
|
|
|
validate_response('UpdatePetWithForm', 405, Body, ValidatorState) ->
|
|
validate_response_body('', '', Body, ValidatorState);
|
|
|
|
validate_response('UploadFile', 200, Body, ValidatorState) ->
|
|
validate_response_body('ApiResponse', 'ApiResponse', Body, ValidatorState);
|
|
|
|
|
|
validate_response('DeleteOrder', 400, Body, ValidatorState) ->
|
|
validate_response_body('', '', Body, ValidatorState);
|
|
validate_response('DeleteOrder', 404, Body, ValidatorState) ->
|
|
validate_response_body('', '', Body, ValidatorState);
|
|
|
|
validate_response('GetInventory', 200, Body, ValidatorState) ->
|
|
validate_response_body('map', 'integer', Body, ValidatorState);
|
|
|
|
validate_response('GetOrderById', 200, Body, ValidatorState) ->
|
|
validate_response_body('Order', 'Order', Body, ValidatorState);
|
|
validate_response('GetOrderById', 400, Body, ValidatorState) ->
|
|
validate_response_body('', '', Body, ValidatorState);
|
|
validate_response('GetOrderById', 404, Body, ValidatorState) ->
|
|
validate_response_body('', '', Body, ValidatorState);
|
|
|
|
validate_response('PlaceOrder', 200, Body, ValidatorState) ->
|
|
validate_response_body('Order', 'Order', Body, ValidatorState);
|
|
validate_response('PlaceOrder', 400, Body, ValidatorState) ->
|
|
validate_response_body('', '', Body, ValidatorState);
|
|
|
|
|
|
validate_response('CreateUser', 0, Body, ValidatorState) ->
|
|
validate_response_body('', '', Body, ValidatorState);
|
|
|
|
validate_response('CreateUsersWithArrayInput', 0, Body, ValidatorState) ->
|
|
validate_response_body('', '', Body, ValidatorState);
|
|
|
|
validate_response('CreateUsersWithListInput', 0, Body, ValidatorState) ->
|
|
validate_response_body('', '', Body, ValidatorState);
|
|
|
|
validate_response('DeleteUser', 400, Body, ValidatorState) ->
|
|
validate_response_body('', '', Body, ValidatorState);
|
|
validate_response('DeleteUser', 404, Body, ValidatorState) ->
|
|
validate_response_body('', '', Body, ValidatorState);
|
|
|
|
validate_response('GetUserByName', 200, Body, ValidatorState) ->
|
|
validate_response_body('User', 'User', Body, ValidatorState);
|
|
validate_response('GetUserByName', 400, Body, ValidatorState) ->
|
|
validate_response_body('', '', Body, ValidatorState);
|
|
validate_response('GetUserByName', 404, Body, ValidatorState) ->
|
|
validate_response_body('', '', Body, ValidatorState);
|
|
|
|
validate_response('LoginUser', 200, Body, ValidatorState) ->
|
|
validate_response_body('binary', 'string', Body, ValidatorState);
|
|
validate_response('LoginUser', 400, Body, ValidatorState) ->
|
|
validate_response_body('', '', Body, ValidatorState);
|
|
|
|
validate_response('LogoutUser', 0, Body, ValidatorState) ->
|
|
validate_response_body('', '', Body, ValidatorState);
|
|
|
|
validate_response('UpdateUser', 400, Body, ValidatorState) ->
|
|
validate_response_body('', '', Body, ValidatorState);
|
|
validate_response('UpdateUser', 404, Body, ValidatorState) ->
|
|
validate_response_body('', '', Body, ValidatorState);
|
|
|
|
|
|
validate_response(_OperationID, _Code, _Body, _ValidatorState) ->
|
|
ok.
|
|
|
|
validate_response_body('list', ReturnBaseType, Body, ValidatorState) ->
|
|
[
|
|
validate(schema, ReturnBaseType, Item, ValidatorState)
|
|
|| Item <- Body];
|
|
|
|
validate_response_body(_, ReturnBaseType, Body, ValidatorState) ->
|
|
validate(schema, ReturnBaseType, Body, ValidatorState).
|
|
|
|
%%%
|
|
validate(Rule = required, Name, Value, _ValidatorState) ->
|
|
case Value of
|
|
undefined -> validation_error(Rule, Name);
|
|
_ -> ok
|
|
end;
|
|
|
|
validate(not_required, _Name, _Value, _ValidatorState) ->
|
|
ok;
|
|
|
|
validate(_, _Name, undefined, _ValidatorState) ->
|
|
ok;
|
|
|
|
validate(Rule = {type, 'integer'}, Name, Value, _ValidatorState) ->
|
|
try
|
|
{ok, openapi_utils:to_int(Value)}
|
|
catch
|
|
error:badarg ->
|
|
validation_error(Rule, Name)
|
|
end;
|
|
|
|
validate(Rule = {type, 'float'}, Name, Value, _ValidatorState) ->
|
|
try
|
|
{ok, openapi_utils:to_float(Value)}
|
|
catch
|
|
error:badarg ->
|
|
validation_error(Rule, Name)
|
|
end;
|
|
|
|
validate(Rule = {type, 'binary'}, Name, Value, _ValidatorState) ->
|
|
case is_binary(Value) of
|
|
true -> ok;
|
|
false -> validation_error(Rule, Name)
|
|
end;
|
|
|
|
validate(_Rule = {type, 'boolean'}, _Name, Value, _ValidatorState) when is_boolean(Value) ->
|
|
{ok, Value};
|
|
|
|
validate(Rule = {type, 'boolean'}, Name, Value, _ValidatorState) ->
|
|
V = binary_to_lower(Value),
|
|
try
|
|
case binary_to_existing_atom(V, utf8) of
|
|
B when is_boolean(B) -> {ok, B};
|
|
_ -> validation_error(Rule, Name)
|
|
end
|
|
catch
|
|
error:badarg ->
|
|
validation_error(Rule, Name)
|
|
end;
|
|
|
|
validate(Rule = {type, 'date'}, Name, Value, _ValidatorState) ->
|
|
case is_binary(Value) of
|
|
true -> ok;
|
|
false -> validation_error(Rule, Name)
|
|
end;
|
|
|
|
validate(Rule = {type, 'datetime'}, Name, Value, _ValidatorState) ->
|
|
case is_binary(Value) of
|
|
true -> ok;
|
|
false -> validation_error(Rule, Name)
|
|
end;
|
|
|
|
validate(Rule = {enum, Values}, Name, Value, _ValidatorState) ->
|
|
try
|
|
FormattedValue = erlang:binary_to_existing_atom(Value, utf8),
|
|
case lists:member(FormattedValue, Values) of
|
|
true -> {ok, FormattedValue};
|
|
false -> validation_error(Rule, Name)
|
|
end
|
|
catch
|
|
error:badarg ->
|
|
validation_error(Rule, Name)
|
|
end;
|
|
|
|
validate(Rule = {max, Max}, Name, Value, _ValidatorState) ->
|
|
case Value =< Max of
|
|
true -> ok;
|
|
false -> validation_error(Rule, Name)
|
|
end;
|
|
|
|
validate(Rule = {exclusive_max, ExclusiveMax}, Name, Value, _ValidatorState) ->
|
|
case Value > ExclusiveMax of
|
|
true -> ok;
|
|
false -> validation_error(Rule, Name)
|
|
end;
|
|
|
|
validate(Rule = {min, Min}, Name, Value, _ValidatorState) ->
|
|
case Value >= Min of
|
|
true -> ok;
|
|
false -> validation_error(Rule, Name)
|
|
end;
|
|
|
|
validate(Rule = {exclusive_min, ExclusiveMin}, Name, Value, _ValidatorState) ->
|
|
case Value =< ExclusiveMin of
|
|
true -> ok;
|
|
false -> validation_error(Rule, Name)
|
|
end;
|
|
|
|
validate(Rule = {max_length, MaxLength}, Name, Value, _ValidatorState) ->
|
|
case size(Value) =< MaxLength of
|
|
true -> ok;
|
|
false -> validation_error(Rule, Name)
|
|
end;
|
|
|
|
validate(Rule = {min_length, MinLength}, Name, Value, _ValidatorState) ->
|
|
case size(Value) >= MinLength of
|
|
true -> ok;
|
|
false -> validation_error(Rule, Name)
|
|
end;
|
|
|
|
validate(Rule = {pattern, Pattern}, Name, Value, _ValidatorState) ->
|
|
{ok, MP} = re:compile(Pattern),
|
|
case re:run(Value, MP) of
|
|
{match, _} -> ok;
|
|
_ -> validation_error(Rule, Name)
|
|
end;
|
|
|
|
validate(Rule = schema, Name, Value, ValidatorState) ->
|
|
Definition = list_to_binary("#/components/schemas/" ++ openapi_utils:to_list(Name)),
|
|
try
|
|
_ = validate_with_schema(Value, Definition, ValidatorState),
|
|
ok
|
|
catch
|
|
throw:[{schema_invalid, _, Error} | _] ->
|
|
Info = #{
|
|
type => schema_invalid,
|
|
error => Error
|
|
},
|
|
validation_error(Rule, Name, Info);
|
|
throw:[{data_invalid, Schema, Error, _, Path} | _] ->
|
|
Info = #{
|
|
type => data_invalid,
|
|
error => Error,
|
|
schema => Schema,
|
|
path => Path
|
|
},
|
|
validation_error(Rule, Name, Info)
|
|
end;
|
|
|
|
validate(Rule, Name, _Value, _ValidatorState) ->
|
|
error_logger:info_msg("Can't validate ~p with ~p", [Name, Rule]),
|
|
error({unknown_validation_rule, Rule}).
|
|
|
|
-spec validation_error(Rule :: any(), Name :: any()) -> no_return().
|
|
|
|
validation_error(ViolatedRule, Name) ->
|
|
validation_error(ViolatedRule, Name, #{}).
|
|
|
|
-spec validation_error(Rule :: any(), Name :: any(), Info :: #{}) -> no_return().
|
|
|
|
validation_error(ViolatedRule, Name, Info) ->
|
|
throw({wrong_param, Name, ViolatedRule, Info}).
|
|
|
|
-spec get_value(body | qs_val | header | binding, Name :: any(), Req0 :: cowboy_req:req()) ->
|
|
{Value :: any(), Req :: cowboy_req:req()} |
|
|
{error, Reason :: any(), Req :: cowboy_req:req()}.
|
|
get_value(body, _Name, Req0) ->
|
|
{ok, Body, Req} = cowboy_req:read_body(Req0),
|
|
case prepare_body(Body) of
|
|
{error, Reason} ->
|
|
{error, Reason, Req};
|
|
Value ->
|
|
{Value, Req}
|
|
end;
|
|
|
|
get_value(qs_val, Name, Req) ->
|
|
QS = cowboy_req:parse_qs(Req),
|
|
Value = openapi_utils:get_opt(openapi_utils:to_qs(Name), QS),
|
|
{Value, Req};
|
|
|
|
get_value(header, Name, Req) ->
|
|
Headers = cowboy_req:headers(Req),
|
|
Value = maps:get(openapi_utils:to_header(Name), Headers, undefined),
|
|
{Value, Req};
|
|
|
|
get_value(binding, Name, Req) ->
|
|
Value = cowboy_req:binding(openapi_utils:to_binding(Name), Req),
|
|
{Value, Req}.
|
|
|
|
prepare_body(Body) ->
|
|
case Body of
|
|
<<"">> -> <<"">>;
|
|
_ ->
|
|
try
|
|
jsx:decode(Body, [return_maps])
|
|
catch
|
|
error:_ ->
|
|
{error, {invalid_body, not_json, Body}}
|
|
end
|
|
end.
|
|
|
|
validate_with_schema(Body, Definition, ValidatorState) ->
|
|
jesse_schema_validator:validate_with_state(
|
|
[{<<"$ref">>, Definition}],
|
|
Body,
|
|
ValidatorState
|
|
).
|
|
|
|
prepare_param(Rules, Name, Value, ValidatorState) ->
|
|
try
|
|
Result = lists:foldl(
|
|
fun(Rule, Acc) ->
|
|
case validate(Rule, Name, Acc, ValidatorState) of
|
|
ok -> Acc;
|
|
{ok, Prepared} -> Prepared
|
|
end
|
|
end,
|
|
Value,
|
|
Rules
|
|
),
|
|
{ok, Result}
|
|
catch
|
|
throw:Reason ->
|
|
{error, Reason}
|
|
end.
|
|
|
|
binary_to_lower(V) when is_binary(V) ->
|
|
list_to_binary(string:to_lower(openapi_utils:to_list(V))).
|