1- import  type   {  MapKeysResult ,  MappingResolver  }  from  '../types' 
1+ import  {  MapKeysResult ,  MappingResolver ,   NodeContext  }  from  '../types' 
22import  {  getStringValue ,  objectKeys ,  onlyExistedArrayIndexes  }  from  '../utils' 
33import  {  mapPathParams  }  from  './openapi3.utils' 
4+ import  {  OpenAPIV3  }  from  'openapi-types' 
45
56export  const  singleOperationPathMappingResolver : MappingResolver < string >  =  ( before ,  after )  =>  { 
67
@@ -23,18 +24,18 @@ export const singleOperationPathMappingResolver: MappingResolver<string> = (befo
2324  return  result 
2425} 
2526
26- export  const  pathMappingResolver : MappingResolver < string >  =  ( before ,  after )  =>  { 
27+ export  const  pathMappingResolver : MappingResolver < string >  =  ( before ,  after ,   ctx )  =>  { 
2728
2829  const  result : MapKeysResult < string >  =  {  added : [ ] ,  removed : [ ] ,  mapped : { }  } 
2930
3031  const  originalBeforeKeys  =  objectKeys ( before ) 
3132  const  originalAfterKeys  =  objectKeys ( after ) 
32-   const  unifiedAfterKeys  =  originalAfterKeys . map ( hidePathParamNames ) 
33+   const  unifiedAfterKeys  =  originalAfterKeys . map ( unifyPath ( ctx . after ) ) 
3334
3435  const  notMappedAfterIndices  =  new  Set ( originalAfterKeys . keys ( ) ) 
3536
3637  originalBeforeKeys . forEach ( beforeKey  =>  { 
37-     const  unifiedBeforePath  =  hidePathParamNames ( beforeKey ) 
38+     const  unifiedBeforePath  =  unifyPath ( ctx . before ) ( beforeKey ) 
3839    const  index  =  unifiedAfterKeys . indexOf ( unifiedBeforePath ) 
3940
4041    if  ( index  <  0 )  { 
@@ -175,6 +176,35 @@ function isWildcardCompatible(beforeType: string, afterType: string): boolean {
175176  return  true 
176177} 
177178
179+ // todo copy-paste from api-processor 
180+ export  const  extractOperationBasePath  =  ( servers ?: OpenAPIV3 . ServerObject [ ] ) : string  =>  { 
181+   if  ( ! Array . isArray ( servers )  ||  ! servers . length )  {  return  ''  } 
182+ 
183+   try  { 
184+     const  [ firstServer ]  =  servers 
185+     let  serverUrl  =  firstServer . url 
186+     const  {  variables =  { }  }  =  firstServer 
187+ 
188+     for  ( const  param  of  Object . keys ( variables ) )  { 
189+       serverUrl  =  serverUrl . replace ( new  RegExp ( `{${ param }  }` ,  'g' ) ,  variables [ param ] . default ) 
190+     } 
191+ 
192+     const  {  pathname }  =  new  URL ( serverUrl ,  'https://localhost' ) 
193+     return  pathname . slice ( - 1 )  ===  '/'  ? pathname . slice ( 0 ,  - 1 )  : pathname 
194+   }  catch  ( error )  { 
195+     return  '' 
196+   } 
197+ } 
198+ 
199+ export  function  unifyPath ( nodeContext : NodeContext ) : ( path : string )  =>  string  { 
200+   const  serverPrefix  =  extractOperationBasePath ( ( nodeContext . root  as  OpenAPIV3 . Document ) . servers )  // /api/v2 
201+   return  ( path )  =>  ( 
202+     serverPrefix 
203+       ? `${ serverPrefix } ${ hidePathParamNames ( path ) }  ` 
204+       : hidePathParamNames ( path ) 
205+   ) 
206+ } 
207+ 
178208export  function  hidePathParamNames ( path : string ) : string  { 
179209  return  path . replace ( PATH_PARAMETER_REGEXP ,  PATH_PARAM_UNIFIED_PLACEHOLDER ) 
180210} 
0 commit comments