openapi3-code-generator-0.2.0.0: src/OpenAPI/Generate/Internal/Unknown.hs
{-# LANGUAGE OverloadedStrings #-}
module OpenAPI.Generate.Internal.Unknown
( warnAboutUnknownWhiteListedOrOpaqueSchemas,
warnAboutUnknownOperations,
)
where
import Control.Monad
import qualified Data.List as L
import qualified Data.Maybe as Maybe
import qualified Data.Ord as Ord
import qualified Data.Set as Set
import Data.Text (Text)
import qualified Data.Text as T
import qualified OpenAPI.Generate.Monad as OAM
import qualified OpenAPI.Generate.OptParse as OAO
import qualified OpenAPI.Generate.Types as OAT
import qualified OpenAPI.Generate.Types.Schema as OAS
-- | Warn about operations listed as CLI options which do not appear in the provided OpenAPI specification
warnAboutUnknownOperations :: [(Text, OAT.PathItemObject)] -> OAM.Generator ()
warnAboutUnknownOperations operationDefinitions = do
let getAllOperationObjectsFromPathItemObject = ([OAT.pathItemObjectGet, OAT.pathItemObjectPut, OAT.pathItemObjectPost, OAT.pathItemObjectDelete, OAT.pathItemObjectOptions, OAT.pathItemObjectHead, OAT.pathItemObjectPatch, OAT.pathItemObjectTrace] <*>) . pure
operationIds =
Maybe.mapMaybe OAT.operationObjectOperationId $
Maybe.catMaybes $
operationDefinitions >>= getAllOperationObjectsFromPathItemObject . snd
operationsToGenerate <- OAM.getSetting OAO.settingOperationsToGenerate
printWarningIfUnknown (\operationId proposedOptions -> "The operation '" <> operationId <> "' which is listed for generation does not appear in the provided OpenAPI specification. " <> proposedOptions) operationIds operationsToGenerate
-- | Warn about schemas listed as CLI options (white list or opaque schemas) which do not appear in the provided OpenAPI specification
warnAboutUnknownWhiteListedOrOpaqueSchemas :: [(Text, OAS.Schema)] -> OAM.Generator ()
warnAboutUnknownWhiteListedOrOpaqueSchemas schemaDefinitions = do
let schemaNames = fst <$> schemaDefinitions
printWarningIfUnknownWithTypeName typeName = printWarningIfUnknown (\name proposedOptions -> "The " <> typeName <> " '" <> name <> "' does not appear in the provided OpenAPI specification. " <> proposedOptions) schemaNames
whiteListedSchemas <- OAM.getSetting OAO.settingWhiteListedSchemas
opaqueSchemas <- OAM.getSetting OAO.settingOpaqueSchemas
printWarningIfUnknownWithTypeName "white-listed schema" whiteListedSchemas
printWarningIfUnknownWithTypeName "schema listed as opaque" opaqueSchemas
printWarningIfUnknown :: (Text -> Text -> Text) -> [Text] -> [Text] -> OAM.Generator ()
printWarningIfUnknown generateMessage namesFromSpecification =
mapM_
( \name ->
unless (name `elem` namesFromSpecification) $
OAM.logWarning $
generateMessage name $
getProposedOptionsFromNameAndAvailableSchemas name namesFromSpecification
)
getProposedOptionsFromNameAndAvailableSchemas :: Text -> [Text] -> Text
getProposedOptionsFromNameAndAvailableSchemas name = getProposedOptions . sortByLongestCommonSubstring name
sortByLongestCommonSubstring :: Text -> [Text] -> [Text]
sortByLongestCommonSubstring needle = fmap fst . L.sortOn snd . fmap (\x -> (x, -(longestCommonSubstringCount needle x)))
getProposedOptions :: [Text] -> Text
getProposedOptions [] = "Specification does not contain any."
getProposedOptions (x1 : x2 : x3 : _ : _) = getProposedOptions [x1, x2, x3]
getProposedOptions xs =
let separator = "\n "
in "Did you mean one of following options?" <> separator <> T.intercalate separator xs
longestCommonSubstringCount :: Text -> Text -> Int
longestCommonSubstringCount x y =
let getSetWithAllSubstrings = Set.fromList . (T.inits <=< T.tails) . T.toLower
intersection = Set.intersection (getSetWithAllSubstrings x) (getSetWithAllSubstrings y)
in if Set.null intersection then 0 else T.length (L.maximumBy (Ord.comparing T.length) intersection)