@@ -178,10 +178,11 @@ export function decoratorExtractor(node: Node): RouteInfo | null {
178178 return null
179179 }
180180
181- // Skip comment nodes to find the actual first argument
182- const pathArgNode = argumentsNode . namedChildren . find (
181+ // Find path: first positional arg, or "path" keyword argument
182+ const nonCommentArgs = argumentsNode . namedChildren . filter (
183183 ( child ) => child . type !== "comment" ,
184184 )
185+ const pathArgNode = resolveArgNode ( nonCommentArgs , 0 , "path" )
185186 const path = pathArgNode ? extractPathFromNode ( pathArgNode ) : ""
186187
187188 // For api_route, extract methods from keyword argument
@@ -371,6 +372,33 @@ export function importExtractor(node: Node): ImportInfo | null {
371372 return { modulePath, names, namedImports, isRelative, relativeDots }
372373}
373374
375+ /**
376+ * Resolves a function argument value node by positional index or keyword name.
377+ *
378+ * Examples:
379+ * app.get("/users", response_model=List[User]) → position 0 = string node "/users"
380+ * app.get(path="/users", response_model=List[User]) → keyword "path" = string node "/users"
381+ */
382+ function resolveArgNode (
383+ args : Node [ ] ,
384+ position : number ,
385+ keywordName : string ,
386+ ) : Node | undefined {
387+ const positional = args . filter ( ( a ) => a . type !== "keyword_argument" )
388+ if ( positional [ position ] ) {
389+ return positional [ position ]
390+ }
391+ return (
392+ args
393+ . find (
394+ ( a ) =>
395+ a . type === "keyword_argument" &&
396+ a . childForFieldName ( "name" ) ?. text === keywordName ,
397+ )
398+ ?. childForFieldName ( "value" ) ?? undefined
399+ )
400+ }
401+
374402/** Extracts method call info: object.method(args) */
375403function extractMethodCall (
376404 node : Node ,
@@ -420,9 +448,12 @@ export function includeRouterExtractor(node: Node): IncludeRouterInfo | null {
420448 }
421449 }
422450
451+ // Find router: first positional arg, or "router" keyword argument
452+ const routerNode = resolveArgNode ( call . args , 0 , "router" )
453+
423454 return {
424455 owner : call . object ,
425- router : call . args [ 0 ] ?. text ?? "" ,
456+ router : routerNode ?. text ?? "" ,
426457 prefix,
427458 tags,
428459 }
@@ -435,9 +466,13 @@ export function mountExtractor(node: Node): MountInfo | null {
435466 return null
436467 }
437468
469+ // Find path and app: positional or keyword argument style
470+ const pathNode = resolveArgNode ( call . args , 0 , "path" )
471+ const appNode = resolveArgNode ( call . args , 1 , "app" )
472+
438473 return {
439474 owner : call . object ,
440- path : extractPathFromNode ( call . args [ 0 ] ) ,
441- app : call . args [ 1 ] . text ,
475+ path : pathNode ? extractPathFromNode ( pathNode ) : "" ,
476+ app : appNode ?. text ?? "" ,
442477 }
443478}
0 commit comments