@@ -6,163 +6,28 @@ module OpenAPI.Checker.Validate.OpenApi
10import Data.HList
9import Data.HList
11import qualified Data.HashMap.Strict.InsOrd as IOHM
10import qualified Data.HashMap.Strict.InsOrd as IOHM
13import Data.OpenApi
11import Data.OpenApi
15import OpenAPI.Checker.Subtree
12import OpenAPI.Checker.Subtree
16import OpenAPI.Checker.Trace
13import OpenAPI.Checker.Trace
17−import OpenAPI.Checker.Validate.Operation
14+import OpenAPI.Checker.Validate.ProcessedPathItem
18−import OpenAPI.Checker.Validate.PathFragment
20instance Subtree OpenApi where
16instance Subtree OpenApi where
21 type CheckEnv OpenApi = '[]
17 type CheckEnv OpenApi = '[]
22− data CheckIssue OpenApi = NoPathsMatched | WrongNumberOfFragments
18+ data CheckIssue OpenApi
23 deriving (Eq, Ord, Show)
19 deriving (Eq, Ord, Show)
24 normalizeTrace = undefined
20 normalizeTrace = undefined
25 checkCompatibility _ prodCons = do
21 checkCompatibility _ prodCons = do
26− let ProdCons {producer = p, consumer = c} = processOpenApi <$> prodCons
31− [ localTrace (step <$> ProdCons pSPath cSPath) $ do
32− -- make sure every path fragment is compatible
34− [ localTrace (pure . step $ PathFragmentStep i) $
35− checkCompatibility (singletonH $ ProdCons pPathFragmentParams cPathFragmentParams) pair
36− | (i, pair) <- zip [0 ..] pathFragments
38− -- make sure the operation is compatible.
39− localTrace (pure . step $ getter stepProcessedPathItem) $
40− checkCompatibility HNil $ ProdCons pOperation cOperation
42− | (cSPath, cPath, cPathItem) <- c
43− , -- ... and try to match it with every endpoint in the consumer.
45− -- This is required because the meaning of path fragments can change on
46− -- a per-method basis even within the same 'PathItem'
48− -- Here we only need to look for the method that the current producer
49− -- endpoint is using.
50− (cParams, cOperation) <- maybeToList $ getter cPathItem
51− , let cPathFragmentParams = retrace (step PathFragmentParentStep >>>) <$> cParams
52− , -- make sure the paths are the same length
53− pathFragments <- maybeToList $ zipAllWith ProdCons pPath cPath
55− | (pSPath, pPath, pPathItem) <- p
56− , -- look at every endpoint in the producer ...
57− (ProcessedPathItemGetter getter, (pParams, pOperation)) <-
58− toList (fmap . (,) <$> processedPathItemGetters <*> pPathItem) >>= maybeToList
59− , let pPathFragmentParams = retrace (step PathFragmentParentStep >>>) <$> pParams
62−zipAllWith :: (a -> b -> c) -> [a] -> [b] -> Maybe [c]
63−zipAllWith _ [] [] = Just []
64−zipAllWith f (x : xs) (y : ys) = (f x y :) <$> zipAllWith f xs ys
65−zipAllWith _ (_ : _) [] = Nothing
66−zipAllWith _ [] (_ : _) = Nothing
70− -> [ ( Step OpenApi PathItem
72− , ForeachOperation (Maybe (TracedReferences PathItem Param, Operation))
76− let cs = _openApiComponents o
22+ let cs = _openApiComponents <$> prodCons
23+ localStep OpenApiPathsStep $
25+ ((_componentsRequestBodies <$> cs)
26+ `HCons` (_componentsParameters <$> cs)
27+ `HCons` (_componentsSecuritySchemes <$> cs)
77− (pathS, pathItem) <- IOHM.toList . _openApiPaths $ o
29+ (processPathItems . IOHM.toList . _openApiPaths <$> prodCons)
78− let path = parsePath pathS
30+
79− componentParams = _componentsParameters cs
81− retrace (step PathItemParametersStep >>>)
82− <$> getPathParamRefs componentParams (_pathItemParameters pathItem)
83− processOperation (s :: Step PathItem Operation) op =
84− let operationParams =
85− retrace (Root `Snoc` s `Snoc` OperationParametersStep >>>)
86− <$> getPathParamRefs componentParams (_operationParameters op)
88− operationParams <> commonPathParams
93− , fmap . processOperation
94− <$> stepProcessedPathItem
96− { processedPathItemGet = _pathItemGet pathItem
97− , processedPathItemPut = _pathItemPut pathItem
98− , processedPathItemPost = _pathItemPost pathItem
99− , processedPathItemDelete = _pathItemDelete pathItem
100− , processedPathItemOptions = _pathItemOptions pathItem
101− , processedPathItemHead = _pathItemHead pathItem
102− , processedPathItemPatch = _pathItemPatch pathItem
103− , processedPathItemTrace = _pathItemTrace pathItem
107−instance Steppable OpenApi PathItem where
31+instance Steppable OpenApi ProcessedPathItems where
108− data Step OpenApi PathItem = PathStep FilePath
32+ data Step OpenApi ProcessedPathItems = OpenApiPathsStep
109− deriving (Eq, Ord, Show)
111−instance Steppable PathItem PathFragment where
112− data Step PathItem PathFragment
113− = -- | The index of the path item
114− PathFragmentStep Int
115− deriving (Eq, Ord, Show)
117−instance Steppable PathFragment PathItem where
118− data Step PathFragment PathItem = PathFragmentParentStep
119 deriving (Eq, Ord, Show)
33 deriving (Eq, Ord, Show)
121−instance Steppable PathItem (Referenced Param) where
122− data Step PathItem (Referenced Param) = PathItemParametersStep
123− deriving (Eq, Ord, Show)
125−instance Steppable Operation (Referenced Param) where
126− data Step Operation (Referenced Param) = OperationParametersStep
127− deriving (Eq, Ord, Show)
129−data ForeachOperation a = ForeachOperation
130− { processedPathItemGet :: a
131− , processedPathItemPut :: a
132− , processedPathItemPost :: a
133− , processedPathItemDelete :: a
134− , processedPathItemOptions :: a
135− , processedPathItemHead :: a
136− , processedPathItemPatch :: a
137− , processedPathItemTrace :: a
139− deriving stock (Functor, Generic1)
140− deriving (Applicative, Foldable) via Generically1 ForeachOperation
142−newtype ProcessedPathItemGetter = ProcessedPathItemGetter (forall a. ForeachOperation a -> a)
144−processedPathItemGetters :: ForeachOperation ProcessedPathItemGetter
145−processedPathItemGetters =
147− { processedPathItemGet = ProcessedPathItemGetter processedPathItemGet
148− , processedPathItemPut = ProcessedPathItemGetter processedPathItemPut
149− , processedPathItemPost = ProcessedPathItemGetter processedPathItemPost
150− , processedPathItemDelete = ProcessedPathItemGetter processedPathItemDelete
151− , processedPathItemOptions = ProcessedPathItemGetter processedPathItemOptions
152− , processedPathItemHead = ProcessedPathItemGetter processedPathItemHead
153− , processedPathItemPatch = ProcessedPathItemGetter processedPathItemPatch
154− , processedPathItemTrace = ProcessedPathItemGetter processedPathItemTrace
157−stepProcessedPathItem :: ForeachOperation (Step PathItem Operation)
158−stepProcessedPathItem =
160− { processedPathItemGet = GetStep
161− , processedPathItemPut = PutStep
162− , processedPathItemPost = PostStep
163− , processedPathItemDelete = DeleteStep
164− , processedPathItemOptions = OptionsStep
165− , processedPathItemHead = HeadStep
166− , processedPathItemPatch = PatchStep
167− , processedPathItemTrace = TraceStep