@@ -4,6 +4,36 @@ import { createRef } from "../lib/utils.js";
4
4
import type { ParameterObject , ReferenceObject , TransformNodeOptions } from "../types.js" ;
5
5
import transformParameterObject from "./parameter-object.js" ;
6
6
7
+ // Regex to match path parameters in URL
8
+ const PATH_PARAM_RE = / \{ ( [ ^ } ] + ) \} / g;
9
+
10
+ /**
11
+ * Create a synthetic path parameter object from a parameter name
12
+ */
13
+ function createPathParameter ( paramName : string ) : ParameterObject {
14
+ return {
15
+ name : paramName ,
16
+ in : "path" ,
17
+ required : true ,
18
+ schema : { type : "string" } ,
19
+ } ;
20
+ }
21
+
22
+ /**
23
+ * Extract path parameters from a URL
24
+ */
25
+ function extractPathParamsFromUrl ( path : string ) : ParameterObject [ ] {
26
+ const params : ParameterObject [ ] = [ ] ;
27
+ const matches = path . match ( PATH_PARAM_RE ) ;
28
+ if ( matches ) {
29
+ for ( const match of matches ) {
30
+ const paramName = match . slice ( 1 , - 1 ) ;
31
+ params . push ( createPathParameter ( paramName ) ) ;
32
+ }
33
+ }
34
+ return params ;
35
+ }
36
+
7
37
/**
8
38
* Synthetic type. Array of (ParameterObject | ReferenceObject)s found in OperationObject and PathItemObject.
9
39
*/
@@ -13,14 +43,36 @@ export function transformParametersArray(
13
43
) : ts . TypeElement [ ] {
14
44
const type : ts . TypeElement [ ] = [ ] ;
15
45
46
+ // Create a working copy of parameters array
47
+ const workingParameters = [ ...parametersArray ] ;
48
+
49
+ // Generate path parameters if enabled
50
+ if ( options . ctx . generatePathParams && options . path ) {
51
+ const pathString = Array . isArray ( options . path ) ? options . path [ 0 ] : options . path ;
52
+ if ( typeof pathString === "string" ) {
53
+ const pathParams = extractPathParamsFromUrl ( pathString ) ;
54
+ // Only add path parameters that aren't already defined
55
+ for ( const param of pathParams ) {
56
+ const exists = workingParameters . some ( ( p ) => {
57
+ const resolved = "$ref" in p ? options . ctx . resolve < ParameterObject > ( p . $ref ) : p ;
58
+ return resolved ?. in === "path" && resolved ?. name === param . name ;
59
+ } ) ;
60
+ if ( ! exists ) {
61
+ workingParameters . push ( param ) ;
62
+ }
63
+ }
64
+ }
65
+ }
66
+
16
67
// parameters
17
68
const paramType : ts . TypeElement [ ] = [ ] ;
18
69
for ( const paramIn of [ "query" , "header" , "path" , "cookie" ] as ParameterObject [ "in" ] [ ] ) {
19
70
const paramLocType : ts . TypeElement [ ] = [ ] ;
20
- let operationParameters = parametersArray . map ( ( param ) => ( {
71
+ let operationParameters = workingParameters . map ( ( param ) => ( {
21
72
original : param ,
22
73
resolved : "$ref" in param ? options . ctx . resolve < ParameterObject > ( param . $ref ) : param ,
23
74
} ) ) ;
75
+
24
76
// this is the only array type in the spec, so we have to one-off sort here
25
77
if ( options . ctx . alphabetize ) {
26
78
operationParameters . sort ( ( a , b ) => ( a . resolved ?. name ?? "" ) . localeCompare ( b . resolved ?. name ?? "" ) ) ;
0 commit comments