Skip to content

Commit 3af46b5

Browse files
authored
Merge pull request #282 from zupo/fix/path-level-params
Support path-level parameters in code generation
2 parents 1121fcb + 36de1eb commit 3af46b5

4 files changed

Lines changed: 276 additions & 24 deletions

File tree

cli/example/path-level-params.yaml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
openapi: "3.1.0"
2+
info:
3+
title: "Path Level Params Test"
4+
version: "1.0.0"
5+
paths:
6+
/orgs/{orgId}/teams/{teamId}/items:
7+
parameters:
8+
- $ref: '#/components/parameters/orgIdParam'
9+
- in: path
10+
name: teamId
11+
required: true
12+
schema:
13+
type: string
14+
get:
15+
operationId: getItems
16+
parameters:
17+
- in: query
18+
name: status
19+
required: false
20+
schema:
21+
type: string
22+
responses:
23+
"200":
24+
description: OK
25+
content:
26+
application/json:
27+
schema:
28+
type: object
29+
properties:
30+
count:
31+
type: integer
32+
required:
33+
- count
34+
components:
35+
parameters:
36+
orgIdParam:
37+
in: path
38+
name: orgId
39+
required: true
40+
schema:
41+
type: string

cli/src/TestGenScript.elm

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ run =
7777
OpenApi.Config.inputFrom (OpenApi.Config.File "./example/overriding-global-security.yaml")
7878
|> OpenApi.Config.withOverrides [ OpenApi.Config.File "./example/overriding-global-security-override.yaml" ]
7979

80+
pathLevelParams : OpenApi.Config.Input
81+
pathLevelParams =
82+
OpenApi.Config.inputFrom (OpenApi.Config.File "./example/path-level-params.yaml")
83+
8084
patreon : OpenApi.Config.Input
8185
patreon =
8286
OpenApi.Config.inputFrom (OpenApi.Config.File "./example/patreon.json")
@@ -143,6 +147,7 @@ run =
143147
|> OpenApi.Config.withInput multipartFormData
144148
|> OpenApi.Config.withInput nullableEnum
145149
|> OpenApi.Config.withInput overridingGlobalSecurity
150+
|> OpenApi.Config.withInput pathLevelParams
146151
|> OpenApi.Config.withInput realworldConduit
147152
|> OpenApi.Config.withInput recursiveAllOfRefs
148153
|> OpenApi.Config.withInput simpleRef

src/OpenApi/Generate.elm

Lines changed: 61 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,42 @@ stripTrailingSlash input =
281281
input
282282

283283

284+
{-| Merge path-level parameters with operation-level parameters.
285+
Per the OpenAPI spec, operation-level parameters override path-level
286+
parameters with the same name and location.
287+
-}
288+
mergeParams :
289+
List (OpenApi.Reference.ReferenceOr OpenApi.Parameter.Parameter)
290+
-> List (OpenApi.Reference.ReferenceOr OpenApi.Parameter.Parameter)
291+
-> CliMonad (List (OpenApi.Reference.ReferenceOr OpenApi.Parameter.Parameter))
292+
mergeParams pathParams operationParams =
293+
let
294+
paramKey : OpenApi.Reference.ReferenceOr OpenApi.Parameter.Parameter -> CliMonad String
295+
paramKey param =
296+
toConcreteParam param
297+
|> CliMonad.map (\concrete -> OpenApi.Parameter.in_ concrete ++ ":" ++ OpenApi.Parameter.name concrete)
298+
in
299+
CliMonad.combineMap paramKey operationParams
300+
|> CliMonad.map FastSet.fromList
301+
|> CliMonad.andThen
302+
(\operationParamKeys ->
303+
pathParams
304+
|> CliMonad.combineMap
305+
(\param ->
306+
paramKey param
307+
|> CliMonad.map
308+
(\key ->
309+
if FastSet.member key operationParamKeys then
310+
Nothing
311+
312+
else
313+
Just param
314+
)
315+
)
316+
|> CliMonad.map (\filtered -> List.filterMap identity filtered ++ operationParams)
317+
)
318+
319+
284320
pathDeclarations : List OpenApi.Config.EffectType -> ServerInfo -> CliMonad (List CliMonad.Declaration)
285321
pathDeclarations effectTypes server =
286322
CliMonad.getApiSpec
@@ -302,7 +338,7 @@ pathDeclarations effectTypes server =
302338
|> List.filterMap (\( method, getter ) -> Maybe.map (Tuple.pair method) (getter path))
303339
|> CliMonad.combineMap
304340
(\( method, operation ) ->
305-
toRequestFunctions server effectTypes method url operation
341+
toRequestFunctions server effectTypes method url (OpenApi.Path.parameters path) operation
306342
|> CliMonad.errorToWarning
307343
)
308344
|> CliMonad.map (List.filterMap identity >> List.concat)
@@ -489,8 +525,17 @@ requestBodyToDeclarations name reference =
489525
|> CliMonad.withPath name
490526

491527

492-
toRequestFunctions : ServerInfo -> List OpenApi.Config.EffectType -> String -> String -> OpenApi.Operation.Operation -> CliMonad (List CliMonad.Declaration)
493-
toRequestFunctions server effectTypes method pathUrl operation =
528+
toRequestFunctions : ServerInfo -> List OpenApi.Config.EffectType -> String -> String -> List (OpenApi.Reference.ReferenceOr OpenApi.Parameter.Parameter) -> OpenApi.Operation.Operation -> CliMonad (List CliMonad.Declaration)
529+
toRequestFunctions server effectTypes method pathUrl pathLevelParams operation =
530+
mergeParams pathLevelParams (OpenApi.Operation.parameters operation)
531+
|> CliMonad.andThen
532+
(\allParams ->
533+
toRequestFunctionsHelp server effectTypes method pathUrl operation allParams
534+
)
535+
536+
537+
toRequestFunctionsHelp : ServerInfo -> List OpenApi.Config.EffectType -> String -> String -> OpenApi.Operation.Operation -> List (OpenApi.Reference.ReferenceOr OpenApi.Parameter.Parameter) -> CliMonad (List CliMonad.Declaration)
538+
toRequestFunctionsHelp server effectTypes method pathUrl operation allParams =
494539
let
495540
step : OperationUtils -> CliMonad (List CliMonad.Declaration)
496541
step ({ successType, bodyTypeAnnotation, errorTypeDeclaration, errorTypeAnnotation } as operationUtils) =
@@ -524,7 +569,7 @@ toRequestFunctions server effectTypes method pathUrl operation =
524569
|> CliMonad.andThen
525570
(\params ->
526571
toConfigParamAnnotation
527-
{ operation = operation
572+
{ allParams = allParams
528573
, successAnnotation = successAnnotation
529574
, errorBodyAnnotation = bodyTypeAnnotation
530575
, errorTypeAnnotation = errorTypeAnnotation
@@ -534,11 +579,11 @@ toRequestFunctions server effectTypes method pathUrl operation =
534579
}
535580
)
536581
)
537-
(replacedUrl server auth pathUrl operation)
582+
(replacedUrl server auth pathUrl allParams)
538583
)
539584
(operationToContentSchema operation)
540585
(operationToAuthorizationInfo operation)
541-
(operationToHeaderParams operation)
586+
(operationToHeaderParams allParams)
542587
(case successType of
543588
SuccessType t ->
544589
SchemaUtils.typeToAnnotationWithNullable t
@@ -1324,10 +1369,9 @@ operationToGroup operation =
13241369
"Operations"
13251370

13261371

1327-
operationToHeaderParams : OpenApi.Operation.Operation -> CliMonad (List (Elm.Expression -> ( Elm.Expression, Elm.Expression, Bool )))
1328-
operationToHeaderParams operation =
1329-
operation
1330-
|> OpenApi.Operation.parameters
1372+
operationToHeaderParams : List (OpenApi.Reference.ReferenceOr OpenApi.Parameter.Parameter) -> CliMonad (List (Elm.Expression -> ( Elm.Expression, Elm.Expression, Bool )))
1373+
operationToHeaderParams params =
1374+
params
13311375
|> CliMonad.combineMap
13321376
(\param ->
13331377
toConcreteParam param
@@ -1373,8 +1417,8 @@ operationToHeaderParams operation =
13731417
|> CliMonad.map (List.filterMap identity)
13741418

13751419

1376-
replacedUrl : ServerInfo -> AuthorizationInfo -> String -> OpenApi.Operation.Operation -> CliMonad (Elm.Expression -> Elm.Expression)
1377-
replacedUrl server authInfo pathUrl operation =
1420+
replacedUrl : ServerInfo -> AuthorizationInfo -> String -> List (OpenApi.Reference.ReferenceOr OpenApi.Parameter.Parameter) -> CliMonad (Elm.Expression -> Elm.Expression)
1421+
replacedUrl server authInfo pathUrl params =
13781422
let
13791423
pathSegments : List String
13801424
pathSegments =
@@ -1452,8 +1496,7 @@ replacedUrl server authInfo pathUrl operation =
14521496
MultipleServers _ ->
14531497
Gen.Url.Builder.call_.crossOrigin (Elm.get "server" config) (Elm.list replacedSegments) allQueryParams
14541498
in
1455-
operation
1456-
|> OpenApi.Operation.parameters
1499+
params
14571500
|> CliMonad.combineMap
14581501
(\param ->
14591502
toConcreteParam param
@@ -1969,7 +2012,7 @@ multipartContent mediaType =
19692012

19702013

19712014
toConfigParamAnnotation :
1972-
{ operation : OpenApi.Operation.Operation
2015+
{ allParams : List (OpenApi.Reference.ReferenceOr OpenApi.Parameter.Parameter)
19732016
, successAnnotation : Elm.Annotation.Annotation
19742017
, errorBodyAnnotation : Elm.Annotation.Annotation
19752018
, errorTypeAnnotation : Elm.Annotation.Annotation
@@ -2029,7 +2072,7 @@ toConfigParamAnnotation options =
20292072
, lamderaProgramTest = toMsgLamderaProgramTest
20302073
}
20312074
)
2032-
(operationToUrlParams options.operation)
2075+
(operationToUrlParams options.allParams)
20332076

20342077

20352078
type ServerInfo
@@ -2095,13 +2138,8 @@ serverInfo server =
20952138
|> CliMonad.succeed
20962139

20972140

2098-
operationToUrlParams : OpenApi.Operation.Operation -> CliMonad (List ( Common.UnsafeName, Elm.Annotation.Annotation ))
2099-
operationToUrlParams operation =
2100-
let
2101-
params : List (OpenApi.Reference.ReferenceOr OpenApi.Parameter.Parameter)
2102-
params =
2103-
OpenApi.Operation.parameters operation
2104-
in
2141+
operationToUrlParams : List (OpenApi.Reference.ReferenceOr OpenApi.Parameter.Parameter) -> CliMonad (List ( Common.UnsafeName, Elm.Annotation.Annotation ))
2142+
operationToUrlParams params =
21052143
if List.isEmpty params then
21062144
CliMonad.succeed []
21072145

0 commit comments

Comments
 (0)