diff --git a/cli/example/nullable-enum.yaml b/cli/example/nullable-enum.yaml index 3479158..a57cc2f 100644 --- a/cli/example/nullable-enum.yaml +++ b/cli/example/nullable-enum.yaml @@ -4,12 +4,15 @@ info: version: 1.0.0 paths: "/": - summary: Does stuff - responses: - 200: - description: Ok - schema: - "#ref": "#/components/schemas/NullableEnum" + get: + summary: Does stuff + responses: + 200: + description: Ok + content: + application/json: + schema: + "$ref": "#/components/schemas/NullableEnum" components: schemas: NullableEnum: diff --git a/cli/example/overriding-global-security.yaml b/cli/example/overriding-global-security.yaml index f745197..5b91ecf 100644 --- a/cli/example/overriding-global-security.yaml +++ b/cli/example/overriding-global-security.yaml @@ -7,6 +7,13 @@ components: Data: description: "Data" type: string + responses: + Data: + description: "Data" + content: + application/json: + schema: + $ref: "#/components/schemas/Data" securitySchemes: Token: type: apiKey @@ -22,7 +29,7 @@ paths: operationId: GetProtectedData responses: 200: - $ref: "#/components/schemas/Data" + $ref: "#/components/responses/Data" "/api/unprotected": get: @@ -32,7 +39,7 @@ paths: security: [] responses: 200: - $ref: "#/components/schemas/Data" + $ref: "#/components/responses/Data" post: summary: Unprotected endpoint to store data # Whoops! Security should be overridden here like for GET. Let's fix it @@ -41,7 +48,7 @@ paths: operationId: PostUnprotectedData responses: 200: - $ref: "#/components/schemas/Data" + $ref: "#/components/responses/Data" patch: summary: Unprotected endpoint to store data (again) # Whoops! This is supposed to be unprotected, like GET. Let's fix it @@ -52,4 +59,4 @@ paths: operationId: PatchUnprotectedData responses: 200: - $ref: "#/components/schemas/Data" + $ref: "#/components/responses/Data" diff --git a/cli/example/recursive-allof-refs.yaml b/cli/example/recursive-allof-refs.yaml index bf2b5bc..89fa2d5 100644 --- a/cli/example/recursive-allof-refs.yaml +++ b/cli/example/recursive-allof-refs.yaml @@ -35,9 +35,13 @@ components: paths: "/api/grand-child": summary: Get a GrandChild object. - description: + description: Example description get: operationId: getGrandChild responses: 200: - $ref: "#/components/schemas/GrandChild" + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/GrandChild" diff --git a/cli/src/Cli.elm b/cli/src/Cli.elm index a1f91b4..61299e6 100644 --- a/cli/src/Cli.elm +++ b/cli/src/Cli.elm @@ -50,6 +50,7 @@ type alias CliOptions = , overrides : List OpenApi.Config.Path , writeMergedTo : Maybe String , noElmFormat : Bool + , keepGoing : Bool } @@ -96,6 +97,8 @@ program = (Cli.Option.optionalKeywordArg "write-merged-to") |> Cli.OptionsParser.with (Cli.Option.flag "no-elm-format") + |> Cli.OptionsParser.with + (Cli.Option.flag "keep-going") |> Cli.OptionsParser.withDoc ([ "" , """version: 0.7.0""" @@ -166,6 +169,7 @@ program = , formatOption "overrides" [ "Load an additional file to override parts of the original Open API file." ] , formatOption "write-merged-to" [ "Write the merged Open API spec to the given file." ] , formatOption "no-elm-format" [ "Don't run elm-format on the outputs." ] + , formatOption "keep-going" [ "If a route can't be generated, skip it instead of erroring out." ] ] |> String.join "\n\n" ) @@ -370,6 +374,7 @@ parseCliOptions cliOptions = |> OpenApi.Config.withGenerateTodos cliOptions.generateTodos |> OpenApi.Config.withAutoConvertSwagger cliOptions.autoConvertSwagger |> OpenApi.Config.withNoElmFormat cliOptions.noElmFormat + |> OpenApi.Config.withKeepGoing cliOptions.keepGoing |> maybe OpenApi.Config.withSwaggerConversionUrl cliOptions.swaggerConversionUrl |> maybe OpenApi.Config.withSwaggerConversionCommand (cliOptions.swaggerConversionCommand diff --git a/cli/src/TestGenScript.elm b/cli/src/TestGenScript.elm index 4eca14b..3fe26ef 100644 --- a/cli/src/TestGenScript.elm +++ b/cli/src/TestGenScript.elm @@ -119,6 +119,7 @@ run = -- Slimmed config for profiling OpenApi.Config.init "./generated" |> OpenApi.Config.withNoElmFormat True + |> OpenApi.Config.withKeepGoing True |> OpenApi.Config.withInput additionalProperties |> OpenApi.Config.withInput recursiveAllofRefs |> OpenApi.Config.withInput overridingGlobalSecurity diff --git a/review/suppressed/Docs.NoMissing.json b/review/suppressed/Docs.NoMissing.json index 41df1d9..61b7845 100644 --- a/review/suppressed/Docs.NoMissing.json +++ b/review/suppressed/Docs.NoMissing.json @@ -3,7 +3,7 @@ "automatically created by": "elm-review suppress", "learn more": "elm-review suppress --help", "suppressions": [ - { "count": 30, "filePath": "src/OpenApi/Config.elm" }, + { "count": 29, "filePath": "src/OpenApi/Config.elm" }, { "count": 5, "filePath": "src/OpenApi/Generate.elm" } ] } diff --git a/src/CliMonad.elm b/src/CliMonad.elm index 0ffd720..dad0b4b 100644 --- a/src/CliMonad.elm +++ b/src/CliMonad.elm @@ -44,6 +44,7 @@ import OpenApi exposing (OpenApi) import OpenApi.Config import Pretty import String.Extra +import Triple.Extra type alias Message = @@ -85,6 +86,7 @@ type alias Input = , namespace : List String , formats : FastDict.Dict InternalFormatName InternalFormat , warnOnMissingEnums : Bool + , keepGoing : Bool } @@ -126,6 +128,7 @@ run : , namespace : List String , formats : List OpenApi.Config.Format , warnOnMissingEnums : Bool + , keepGoing : Bool } -> CliMonad (List Declaration) -> @@ -148,6 +151,7 @@ run oneOfDeclarations input (CliMonad x) = |> List.map toInternalFormat |> FastDict.fromList , warnOnMissingEnums = input.warnOnMissingEnums + , keepGoing = input.keepGoing } res : Result Message ( List Declaration, Output, Cache ) @@ -570,20 +574,28 @@ getApiSpec = CliMonad (\input cache -> Ok ( input.openApi, emptyOutput, cache )) +{-| If the user has chosen to keep going in the face of errors, this will convert an error into a warning. Otherwise this returns the input +-} errorToWarning : CliMonad a -> CliMonad (Maybe a) errorToWarning (CliMonad f) = CliMonad (\input cache -> - case f input cache of - Ok ( res, output, cache2 ) -> - Ok ( Just res, output, cache2 ) + if input.keepGoing then + case f input cache of + Ok ( res, output, cache2 ) -> + Ok ( Just res, output, cache2 ) - Err { path, message } -> - ( Nothing - , { emptyOutput | warnings = [ { path = path, message = message, details = Pretty.empty } ] } - , cache - ) - |> Ok + Err { path, message } -> + ( Nothing + , { emptyOutput | warnings = [ { path = path, message = message, details = Pretty.empty } ] } + , cache + ) + |> Ok + + else + Result.map + (Triple.Extra.mapFirst Just) + (f input cache) ) diff --git a/src/Common.elm b/src/Common.elm index 40ccd31..0d9470e 100644 --- a/src/Common.elm +++ b/src/Common.elm @@ -576,7 +576,7 @@ parseRequestBodyRef ref = Ok (RefTo RequestBody res) else - Err ("Expected a reference to a schema, found a reference to " ++ ref) + Err ("Expected a reference to a request body, found a reference to " ++ ref) ) @@ -589,7 +589,7 @@ parseResponseRef ref = Ok (RefTo Response res) else - Err ("Expected a reference to a schema, found a reference to " ++ ref) + Err ("Expected a reference to a response, found a reference to " ++ ref) ) diff --git a/src/OpenApi/Config.elm b/src/OpenApi/Config.elm index 0a9ea96..bb8779f 100644 --- a/src/OpenApi/Config.elm +++ b/src/OpenApi/Config.elm @@ -1,9 +1,9 @@ module OpenApi.Config exposing ( Config, EffectType(..), effectTypeToPackage, Format, Input, Path(..), Server(..) , init, inputFrom, pathFromString - , withAutoConvertSwagger, AutoConvertSwagger(..), withEffectTypes, withFormat, withFormats, withGenerateTodos, withInput, withSwaggerConversionCommand, withSwaggerConversionUrl, withNoElmFormat + , withAutoConvertSwagger, AutoConvertSwagger(..), withEffectTypes, withFormat, withFormats, withGenerateTodos, withInput, withSwaggerConversionCommand, withSwaggerConversionUrl, withNoElmFormat, withKeepGoing , withOutputModuleName, withOverrides, withServer, withWriteMergedTo, withWarnOnMissingEnums - , autoConvertSwagger, inputs, outputDirectory, swaggerConversionCommand, swaggerConversionUrl, noElmFormat + , autoConvertSwagger, inputs, outputDirectory, swaggerConversionCommand, swaggerConversionUrl, noElmFormat, keepGoing , oasPath, overrides, writeMergedTo , toGenerationConfig, Generate, pathToString , defaultFormats @@ -20,13 +20,13 @@ module OpenApi.Config exposing # Creation @docs init, inputFrom, pathFromString -@docs withAutoConvertSwagger, AutoConvertSwagger, withEffectTypes, withFormat, withFormats, withGenerateTodos, withInput, withSwaggerConversionCommand, withSwaggerConversionUrl, withNoElmFormat +@docs withAutoConvertSwagger, AutoConvertSwagger, withEffectTypes, withFormat, withFormats, withGenerateTodos, withInput, withSwaggerConversionCommand, withSwaggerConversionUrl, withNoElmFormat, withKeepGoing @docs withOutputModuleName, withOverrides, withServer, withWriteMergedTo, withWarnOnMissingEnums # Config properties -@docs autoConvertSwagger, inputs, outputDirectory, swaggerConversionCommand, swaggerConversionUrl, noElmFormat +@docs autoConvertSwagger, inputs, outputDirectory, swaggerConversionCommand, swaggerConversionUrl, noElmFormat, keepGoing # Input properties @@ -83,6 +83,7 @@ type Config , staticFormats : List Format , dynamicFormats : List { format : String, basicType : Common.BasicType } -> List Format , noElmFormat : Bool + , keepGoing : Bool } @@ -208,7 +209,8 @@ type Path | Url Url.Url -- https://petstore3.swagger.io/api/v3/openapi.json -{-| -} +{-| Builds a `Path`. If the file is a valid URL, it will be used as such, otherwise it will be interpreted as a local file path. +-} pathFromString : String -> Path pathFromString path = case Url.fromString path of @@ -230,7 +232,15 @@ pathToString pathType = Url.toString url -{-| -} +{-| Create an empty `Config` with no inputs and a given output directory. + +The default options are to: + + - run elm-format; + - ask before converting Swagger specs to OpenAPI specs; + - fail rather than generating `Debug.todo` or skipping unimplemented paths. + +-} init : String -> Config init initialOutputDirectory = { inputs = [] @@ -242,6 +252,7 @@ init initialOutputDirectory = , staticFormats = defaultFormats , dynamicFormats = \_ -> [] , noElmFormat = False + , keepGoing = False } |> Config @@ -266,7 +277,16 @@ inputFrom path = ------------- -{-| -} +{-| The built-in formats: + + - `date-time` + - `date` + - `uri` + - `uuid` + - `byte` + - `password` + +-} defaultFormats : List Format defaultFormats = [ dateTimeFormat @@ -550,6 +570,11 @@ withNoElmFormat newNoElmFormat (Config config) = Config { config | noElmFormat = newNoElmFormat } +withKeepGoing : Bool -> Config -> Config +withKeepGoing newKeepGoing (Config config) = + Config { config | keepGoing = newKeepGoing } + + ------------- -- Getters -- @@ -592,6 +617,12 @@ noElmFormat (Config config) = config.noElmFormat +{-| -} +keepGoing : Config -> Bool +keepGoing (Config config) = + config.keepGoing + + {-| -} oasPath : Input -> Path oasPath (Input input) = @@ -624,6 +655,7 @@ type alias Generate = , server : Server , formats : List Format , warnOnMissingEnums : Bool + , keepGoing : Bool } @@ -657,6 +689,7 @@ toGenerationConfig formatsInput (Config config) augmentedInputs = , server = input.server , warnOnMissingEnums = input.warnOnMissingEnums , formats = config.staticFormats ++ config.dynamicFormats formatsInput + , keepGoing = config.keepGoing } , spec ) diff --git a/src/OpenApi/Generate.elm b/src/OpenApi/Generate.elm index 6764ac5..3b7faf9 100644 --- a/src/OpenApi/Generate.elm +++ b/src/OpenApi/Generate.elm @@ -119,7 +119,7 @@ files : , warnings : List Message , requiredPackages : FastSet.Set String } -files { namespace, generateTodos, effectTypes, server, formats, warnOnMissingEnums } apiSpec = +files { namespace, generateTodos, effectTypes, server, formats, warnOnMissingEnums, keepGoing } apiSpec = case extractEnums apiSpec of Err e -> Err e @@ -148,6 +148,7 @@ files { namespace, generateTodos, effectTypes, server, formats, warnOnMissingEnu , namespace = namespace , formats = formats , warnOnMissingEnums = warnOnMissingEnums + , keepGoing = keepGoing } |> Result.map (\{ declarations, warnings, requiredPackages } -> diff --git a/tests/Test/OpenApi/Generate.elm b/tests/Test/OpenApi/Generate.elm index 2fe60c4..cbd9f19 100644 --- a/tests/Test/OpenApi/Generate.elm +++ b/tests/Test/OpenApi/Generate.elm @@ -129,6 +129,7 @@ fuzzTitle = , server = OpenApi.Config.Default , formats = OpenApi.Config.defaultFormats , warnOnMissingEnums = True + , keepGoing = False } oas in @@ -257,6 +258,7 @@ pr267 = , server = OpenApi.Config.Default , formats = OpenApi.Config.defaultFormats , warnOnMissingEnums = True + , keepGoing = False } oas in