-module(oaspec@codegen@validate). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/oaspec/codegen/validate.gleam"). -export([error_to_string/1, validate/1]). -export_type([validation_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 validation_error() :: {unsupported_feature, binary(), binary()}. -file("src/oaspec/codegen/validate.gleam", 26). ?DOC(" Convert a validation error to a human-readable string.\n"). -spec error_to_string(validation_error()) -> binary(). error_to_string(Error) -> case Error of {unsupported_feature, Path, Detail} -> <<<<<<"Unsupported feature at "/utf8, Path/binary>>/binary, ": "/utf8>>/binary, Detail/binary>> end. -file("src/oaspec/codegen/validate.gleam", 46). ?DOC(" Validate parameters for unsupported patterns (e.g., deepObject style).\n"). -spec validate_parameters(binary(), list(oaspec@openapi@spec:parameter())) -> list(validation_error()). validate_parameters(Op_id, Params) -> gleam@list:filter_map(Params, fun(Param) -> case erlang:element(7, Param) of {some, <<"deepObject"/utf8>>} -> {ok, {unsupported_feature, <<<>/binary, (erlang:element(2, Param))/binary>>, <<"style: deepObject is not supported. Gleam cannot express deep object query serialization."/utf8>>}}; _ -> {error, nil} end end). -file("src/oaspec/codegen/validate.gleam", 63). ?DOC(" Validate request body for unsupported patterns (e.g., non-JSON content types).\n"). -spec validate_request_body( binary(), gleam@option:option(oaspec@openapi@spec:request_body()) ) -> list(validation_error()). validate_request_body(Op_id, Request_body) -> case Request_body of none -> []; {some, Rb} -> Content_keys = maps:keys(erlang:element(3, Rb)), Non_json = gleam@list:filter( Content_keys, fun(Key) -> Key /= <<"application/json"/utf8>> end ), case Non_json of [] -> []; [Media_type | _] -> [{unsupported_feature, <>, <<<<"Content type '"/utf8, Media_type/binary>>/binary, "' is not supported. Only 'application/json' is supported."/utf8>>}] end end. -file("src/oaspec/codegen/validate.gleam", 202). ?DOC(" Check if any schema in a list is an inline primitive type.\n"). -spec has_inline_primitive_schemas(list(oaspec@openapi@schema:schema_ref())) -> boolean(). has_inline_primitive_schemas(Schemas) -> gleam@list:any(Schemas, fun(S) -> case S of {inline, {string_schema, _, _, _, _, _, _, _}} -> true; {inline, {integer_schema, _, _, _, _, _}} -> true; {inline, {number_schema, _, _, _, _, _}} -> true; {inline, {boolean_schema, _, _}} -> true; _ -> false end end). -file("src/oaspec/codegen/validate.gleam", 124). ?DOC(" Validate oneOf/anyOf schemas: inline primitives are unsupported.\n"). -spec validate_oneof_schemas(binary(), list(oaspec@openapi@schema:schema_ref())) -> list(validation_error()). validate_oneof_schemas(Path, Schemas) -> Has_inline_primitives = has_inline_primitive_schemas(Schemas), case Has_inline_primitives of true -> [{unsupported_feature, Path, <<"oneOf/anyOf with inline primitive types is not supported. Use $ref to named schemas instead."/utf8>>}]; false -> [] end. -file("src/oaspec/codegen/validate.gleam", 112). ?DOC(" Validate inline schemas for unsupported patterns.\n"). -spec validate_schema_inline(binary(), oaspec@openapi@schema:schema_object()) -> list(validation_error()). validate_schema_inline(Path, Schema_obj) -> case Schema_obj of {one_of_schema, _, Schemas, _} -> validate_oneof_schemas(Path, Schemas); {any_of_schema, _, Schemas@1} -> validate_oneof_schemas(Path, Schemas@1); _ -> [] end. -file("src/oaspec/codegen/validate.gleam", 89). ?DOC(" Validate response schemas for inline oneOf with mixed primitives.\n"). -spec validate_responses( binary(), gleam@dict:dict(binary(), oaspec@openapi@spec:response()) ) -> list(validation_error()). validate_responses(Op_id, Responses) -> Entries = maps:to_list(Responses), gleam@list:flat_map( Entries, fun(Entry) -> {Status_code, Response} = Entry, Content_entries = maps:to_list(erlang:element(3, Response)), gleam@list:flat_map( Content_entries, fun(Ce) -> {_, Media_type} = Ce, case erlang:element(2, Media_type) of {some, {inline, Schema_obj}} -> validate_schema_inline( <<<>/binary, Status_code/binary>>, Schema_obj ); _ -> [] end end ) end ). -file("src/oaspec/codegen/validate.gleam", 34). ?DOC(" Validate all operations for unsupported patterns.\n"). -spec validate_operations(oaspec@codegen@context:context()) -> list(validation_error()). validate_operations(Ctx) -> Operations = oaspec@codegen@types:collect_operations(Ctx), gleam@list:flat_map( Operations, fun(Op) -> {Op_id, Operation, _, _} = Op, Param_errors = validate_parameters( Op_id, erlang:element(6, Operation) ), Body_errors = validate_request_body( Op_id, erlang:element(7, Operation) ), Response_errors = validate_responses( Op_id, erlang:element(8, Operation) ), lists:append([Param_errors, Body_errors, Response_errors]) end ). -file("src/oaspec/codegen/validate.gleam", 177). ?DOC(" Validate object properties for unsupported patterns.\n"). -spec validate_object_properties( binary(), gleam@dict:dict(binary(), oaspec@openapi@schema:schema_ref()) ) -> list(validation_error()). validate_object_properties(Path, Properties) -> Entries = maps:to_list(Properties), gleam@list:flat_map( Entries, fun(Entry) -> {Prop_name, Prop_ref} = Entry, Prop_path = <<<>/binary, Prop_name/binary>>, case Prop_ref of {inline, {one_of_schema, _, Schemas, _}} -> validate_oneof_schemas(Prop_path, Schemas); {inline, {any_of_schema, _, Schemas@1}} -> validate_oneof_schemas(Prop_path, Schemas@1); {inline, {object_schema, _, _, _, _, true, _}} -> [{unsupported_feature, Prop_path, <<"additionalProperties: true is not supported. Gleam has no untyped map type."/utf8>>}]; _ -> [] end end ). -file("src/oaspec/codegen/validate.gleam", 153). ?DOC(" Validate a single component schema for unsupported patterns.\n"). -spec validate_component_schema(binary(), oaspec@openapi@schema:schema_ref()) -> list(validation_error()). validate_component_schema(Path, Schema_ref) -> case Schema_ref of {inline, {object_schema, _, Properties, _, _, true, _}} -> Prop_errors = validate_object_properties(Path, Properties), [{unsupported_feature, Path, <<"additionalProperties: true is not supported. Gleam has no untyped map type."/utf8>>} | Prop_errors]; {inline, {object_schema, _, Properties@1, _, _, _, _}} -> validate_object_properties(Path, Properties@1); {inline, {one_of_schema, _, Schemas, _}} -> validate_oneof_schemas(Path, Schemas); {inline, {any_of_schema, _, Schemas@1}} -> validate_oneof_schemas(Path, Schemas@1); _ -> [] end. -file("src/oaspec/codegen/validate.gleam", 141). ?DOC(" Validate component schemas for unsupported patterns.\n"). -spec validate_component_schemas(oaspec@codegen@context:context()) -> list(validation_error()). validate_component_schemas(Ctx) -> Schemas = case erlang:element(5, erlang:element(2, Ctx)) of {some, Components} -> maps:to_list(erlang:element(2, Components)); none -> [] end, gleam@list:flat_map( Schemas, fun(Entry) -> {Name, Schema_ref} = Entry, validate_component_schema( <<"components.schemas."/utf8, Name/binary>>, Schema_ref ) end ). -file("src/oaspec/codegen/validate.gleam", 19). ?DOC( " Validate the parsed spec for unsupported patterns.\n" " Returns a list of errors; empty list means validation passed.\n" ). -spec validate(oaspec@codegen@context:context()) -> list(validation_error()). validate(Ctx) -> Op_errors = validate_operations(Ctx), Schema_errors = validate_component_schemas(Ctx), lists:append(Op_errors, Schema_errors).