@@ -60,12 +60,27 @@ type ProcessResult struct {
6060
6161// DetectPaginationInParams detects pagination strategies in operation parameters
6262func DetectPaginationInParams (params * yaml.Node ) []DetectedPagination {
63+ return DetectPaginationInParamsWithDoc (params , nil )
64+ }
65+
66+ // DetectPaginationInParamsWithDoc detects pagination strategies in operation parameters with document context for $ref resolution
67+ func DetectPaginationInParamsWithDoc (params * yaml.Node , doc * yaml.Node ) []DetectedPagination {
6368 var detected []DetectedPagination
6469
6570 if params == nil || params .Kind != yaml .SequenceNode {
6671 return detected
6772 }
6873
74+ strategyParams := collectStrategyParams (params , doc )
75+
76+ // Convert to DetectedPagination, filtering out weak strategies
77+ detected = filterWeakStrategies (strategyParams )
78+
79+ return detected
80+ }
81+
82+ // collectStrategyParams scans through parameters and collects which strategies each parameter belongs to
83+ func collectStrategyParams (params * yaml.Node , doc * yaml.Node ) map [string ][]string {
6984 strategyParams := make (map [string ][]string )
7085
7186 // Scan through parameters
@@ -74,7 +89,7 @@ func DetectPaginationInParams(params *yaml.Node) []DetectedPagination {
7489 continue
7590 }
7691
77- paramName := getStringValue (param , "name" )
92+ paramName := extractParameterName (param , doc )
7893 if paramName == "" {
7994 continue
8095 }
@@ -89,23 +104,36 @@ func DetectPaginationInParams(params *yaml.Node) []DetectedPagination {
89104 }
90105 }
91106
92- // Convert to DetectedPagination, filtering out weak strategies
107+ return strategyParams
108+ }
109+
110+ // extractParameterName extracts the parameter name from a param node, handling $ref resolution
111+ func extractParameterName (param * yaml.Node , doc * yaml.Node ) string {
112+ var paramName string
113+
114+ // Handle $ref by resolving it first
115+ if ref := getNodeValue (param , "$ref" ); ref != nil && doc != nil {
116+ refPath := ref .Value
117+ resolvedParam := resolveRef (refPath , doc )
118+ if resolvedParam != nil {
119+ paramName = getStringValue (resolvedParam , "name" )
120+ }
121+ } else {
122+ paramName = getStringValue (param , "name" )
123+ }
124+
125+ return paramName
126+ }
127+
128+ // filterWeakStrategies converts strategy params to DetectedPagination, filtering out weak strategies
129+ func filterWeakStrategies (strategyParams map [string ][]string ) []DetectedPagination {
130+ var detected []DetectedPagination
131+
93132 // A strategy is considered "weak" if it only has shared parameters
94133 sharedParams := findSharedParams ()
95134
96135 for strategy , params := range strategyParams {
97- // Check if this strategy has any non-shared parameters
98- hasNonSharedParams := false
99- for _ , param := range params {
100- if ! sharedParams [param ] {
101- hasNonSharedParams = true
102- break
103- }
104- }
105-
106- // Only include strategies that have non-shared parameters
107- // This prevents strategies like "offset" with only "include_totals" from interfering
108- if hasNonSharedParams {
136+ if hasNonSharedParams (params , sharedParams ) {
109137 detected = append (detected , DetectedPagination {
110138 Strategy : strategy ,
111139 Parameters : params ,
@@ -116,6 +144,16 @@ func DetectPaginationInParams(params *yaml.Node) []DetectedPagination {
116144 return detected
117145}
118146
147+ // hasNonSharedParams checks if a strategy has any non-shared parameters
148+ func hasNonSharedParams (params []string , sharedParams map [string ]bool ) bool {
149+ for _ , param := range params {
150+ if ! sharedParams [param ] {
151+ return true
152+ }
153+ }
154+ return false
155+ }
156+
119157// findSharedParams identifies parameters that belong to multiple strategies
120158func findSharedParams () map [string ]bool {
121159 sharedParams := make (map [string ]bool )
@@ -255,7 +293,7 @@ func ProcessEndpointWithDoc(operation *yaml.Node, doc *yaml.Node, opts Options)
255293
256294// detectPaginationStrategies extracts pagination strategies from params and responses
257295func detectPaginationStrategies (params , responses * yaml.Node , doc * yaml.Node ) * paginationStrategies {
258- paramPagination := DetectPaginationInParams (params )
296+ paramPagination := DetectPaginationInParamsWithDoc (params , doc )
259297 responsePagination := DetectPaginationInResponsesWithDoc (responses , doc )
260298
261299 paramStrategies := make (map [string ]bool )
@@ -294,7 +332,7 @@ func needsProcessingCheck(strategies *paginationStrategies, params, responses *y
294332 return true
295333 }
296334
297- if hasOrphanedSharedParams (params , strategies .paramStrategies ) {
335+ if hasOrphanedSharedParamsWithDoc (params , strategies .paramStrategies , doc ) {
298336 return true
299337 }
300338
@@ -317,6 +355,11 @@ func hasResponseCleanupNeeded(strategies *paginationStrategies) bool {
317355
318356// hasOrphanedSharedParams checks for orphaned shared parameters
319357func hasOrphanedSharedParams (params * yaml.Node , paramStrategies map [string ]bool ) bool {
358+ return hasOrphanedSharedParamsWithDoc (params , paramStrategies , nil )
359+ }
360+
361+ // hasOrphanedSharedParamsWithDoc checks for orphaned shared parameters with document context for $ref resolution
362+ func hasOrphanedSharedParamsWithDoc (params * yaml.Node , paramStrategies map [string ]bool , doc * yaml.Node ) bool {
320363 if params == nil {
321364 return false
322365 }
@@ -327,7 +370,20 @@ func hasOrphanedSharedParams(params *yaml.Node, paramStrategies map[string]bool)
327370 continue
328371 }
329372
330- paramName := getStringValue (param , "name" )
373+ var paramName string
374+ var resolvedParam * yaml.Node
375+
376+ // Handle $ref by resolving it first
377+ if ref := getNodeValue (param , "$ref" ); ref != nil && doc != nil {
378+ refPath := ref .Value
379+ resolvedParam = resolveRef (refPath , doc )
380+ if resolvedParam != nil {
381+ paramName = getStringValue (resolvedParam , "name" )
382+ }
383+ } else {
384+ paramName = getStringValue (param , "name" )
385+ }
386+
331387 if paramName == "" || ! sharedParams [paramName ] {
332388 continue
333389 }
@@ -384,7 +440,7 @@ func selectBestStrategy(strategies *paginationStrategies, opts Options) string {
384440// processEndpointCleanup performs the actual cleanup of params and responses
385441func processEndpointCleanup (params , responses * yaml.Node , selectedStrategy string , allPagination []DetectedPagination , doc * yaml.Node , result * ProcessResult ) (* ProcessResult , error ) {
386442 if params != nil {
387- removed := removeUnwantedParams (params , selectedStrategy , allPagination )
443+ removed := removeUnwantedParamsWithDoc (params , selectedStrategy , allPagination , doc )
388444 result .RemovedParams = removed
389445 if len (removed ) > 0 {
390446 result .Changed = true
@@ -405,6 +461,11 @@ func processEndpointCleanup(params, responses *yaml.Node, selectedStrategy strin
405461
406462// removeUnwantedParams removes parameters that don't match the selected strategy
407463func removeUnwantedParams (params * yaml.Node , selectedStrategy string , detected []DetectedPagination ) []string {
464+ return removeUnwantedParamsWithDoc (params , selectedStrategy , detected , nil )
465+ }
466+
467+ // removeUnwantedParamsWithDoc removes parameters that don't match the selected strategy with document context for $ref resolution
468+ func removeUnwantedParamsWithDoc (params * yaml.Node , selectedStrategy string , detected []DetectedPagination , doc * yaml.Node ) []string {
408469 var removed []string
409470
410471 if params .Kind != yaml .SequenceNode {
@@ -420,7 +481,20 @@ func removeUnwantedParams(params *yaml.Node, selectedStrategy string, detected [
420481 continue
421482 }
422483
423- paramName := getStringValue (param , "name" )
484+ var paramName string
485+ var resolvedParam * yaml.Node
486+
487+ // Handle $ref by resolving it first
488+ if ref := getNodeValue (param , "$ref" ); ref != nil && doc != nil {
489+ refPath := ref .Value
490+ resolvedParam = resolveRef (refPath , doc )
491+ if resolvedParam != nil {
492+ paramName = getStringValue (resolvedParam , "name" )
493+ }
494+ } else {
495+ paramName = getStringValue (param , "name" )
496+ }
497+
424498 if paramName == "" {
425499 newContent = append (newContent , param )
426500 continue
0 commit comments