fileoverview import { resolvePath } from './genericFileOps' ; import { NEW_LINE , IMPORT_EXPRESS , REQUIRE_EXPRESS , USE_ROUTER , EXPRESS_ROUTE , REQUIRE_PATH , MULTI_LINE_ROUTE , ROUTE_ENDPOINT , } from '../../constants/expressPatterns' ; const pathUtil = require ( 'path' ) ; param { File } file return { string | undefined } export const findExpressImport = ( file ) : string | undefined => { const LINES = file . contents . split ( NEW_LINE ) ; for ( const LINE of LINES ) { const IMPORT_FOUND = LINE . match ( IMPORT_EXPRESS ) ; if ( IMPORT_FOUND ) return IMPORT_FOUND [ 1 ] ; const REQUIRE_FOUND = LINE . match ( REQUIRE_EXPRESS ) ; if ( REQUIRE_FOUND ) return REQUIRE_FOUND [ 1 ] ; } return undefined ; } ; param { string } line param { string } expressName return { string | undefined } const findExpressInvocation = ( line , expressName ) : string | undefined => { const SERVER_PATTERN = new RegExp ( `(\\S+)\\s*=\\s*${ expressName }\\(\\)` ) ; const INVOCATION_FOUND = line . match ( SERVER_PATTERN ) ; return INVOCATION_FOUND ? INVOCATION_FOUND [ 1 ] : undefined ; } ; param { string } line param { string } expressName return { string | undefined } const findExpressApplication = ( line , expressName ) : string | undefined => { const SERVER_PATTERN = new RegExp ( `\\(\\s*(\\S+)\\s*:\\s*${ expressName }\\.Application\\)` ) ; const APPLICATION_FOUND = line . match ( SERVER_PATTERN ) ; return APPLICATION_FOUND ? APPLICATION_FOUND [ 1 ] : undefined ; } ; param { File } file param { string } expressName return { string | undefined } export const findExpressServer = ( file , expressName ) : string | undefined => { const LINES = file . contents . split ( NEW_LINE ) ; for ( const LINE of LINES ) { const INVOCATION = findExpressInvocation ( LINE , expressName ) ; if ( INVOCATION !== undefined ) return INVOCATION ; const APPLICATION = findExpressApplication ( LINE , expressName ) ; if ( APPLICATION !== undefined ) return APPLICATION ; } return undefined ; } ; param { string } line param { number } portNum return { RouterData [ ] } export const findRouter = ( line , portNum ) : RouterData [ ] => { const ROUTER_FOUND = line . match ( USE_ROUTER ) ; if ( ROUTER_FOUND ) { const LOCAL_ROUTE = ROUTER_FOUND [ 1 ] === '/' ? '' : ROUTER_FOUND [ 1 ] ; const ROUTER_NAME = ROUTER_FOUND [ 2 ] ; return [ { path : '' , baseRoute : `http://localhost:${ portNum }${ LOCAL_ROUTE }` , importName : ROUTER_NAME , } , ] ; } return [ ] ; } ; param { File } file param { number } portNum return { RouterData [ ] } export const findRouters = ( file , portNum ) : RouterData [ ] => { let output = [ ] ; const LINES = file . contents . split ( NEW_LINE ) ; for ( const LINE of LINES ) { output = output . concat ( findRouter ( LINE , portNum ) ) ; } return output ; } ; param { RouterData } router param { string [ ] } fileList param { Map < string , File > } supportFiles return { string } const findRouterFile = ( router , fileList , supportFiles ) : string => { let routerPath = '' ; for ( const element of fileList ) { const FILE = supportFiles . get ( element ) ; if ( FILE !== undefined ) routerPath = findPath ( FILE , router , supportFiles ) ; if ( routerPath !== '' ) break ; } return routerPath ; } ; param { string } line param { RouterData } router return { string [ ] | null } const findRequiredPath = ( line , router ) => { if ( router . path !== '' ) return null ; const REQUIRE_PATTERN = new RegExp ( `{\\s*${ router . importName }\\s*}\\s*=\\s*require\\(\\s*['"\`](\\S+)['"\`]\\)` ) ; return line . match ( REQUIRE_PATTERN ) ; } ; param { string } line param { RouterData } router param { string } path param { Map < string , File > } supportFiles return { string } export const findPathRequire = ( line , router , path , supportFiles ) : string => { let routerPath = '' ; const PATH_FOUND = findRequiredPath ( line , router ) ; if ( PATH_FOUND ) { const FILES = resolvePath ( pathUtil . join ( path , PATH_FOUND [ 1 ] ) . replace ( /\\/g , '/' ) ) ; routerPath = findRouterFile ( router , FILES , supportFiles ) ; } return routerPath ; } ; param { string } line param { RouterData } router param { string } path return { string } const findRouterInit = ( line , router , path ) : string => { let routerPath = '' ; const INIT_PATTERN = new RegExp ( `${ router . importName }\\s*=\\s*\\S*Router\\(.*\\);?` ) ; if ( line . match ( INIT_PATTERN ) ) routerPath = path ; return routerPath ; } ; param { string } line param { RouterData } router param { string } path return { string } const findRouterImport = ( line , router , path ) : string => { let routerPath = '' ; const IMPORT_PATTERN = new RegExp ( `import\\s+${ router . importName }\\s+from\\s+['"\`](\\S+)['"\`];?` ) ; const IMPORT_FOUND = line . match ( IMPORT_PATTERN ) ; if ( IMPORT_FOUND ) { routerPath = resolvePath ( pathUtil . join ( path , IMPORT_FOUND [ 1 ] ) . replace ( /\\/g , '/' ) ) [ 0 ] ; } return routerPath ; } ; param { string } line param { RouterData } router param { string } path return { string } const findJoinRequire = ( line , router , path ) : string => { let routerPath = '' ; const REQUIRE_JOIN_PATTERN = new RegExp ( `${ router . importName }\\s*=\\s*require\\(\\S*\\.join\\(__dirname, ['"\`](\\.*\\/*\\S+)['"\`]\\)` ) ; const REQUIRE_FOUND = line . match ( REQUIRE_JOIN_PATTERN ) ; if ( REQUIRE_FOUND ) { routerPath = resolvePath ( pathUtil . join ( path , REQUIRE_FOUND [ 1 ] ) . replace ( /\\/g , '/' ) ) [ 0 ] ; } return routerPath ; } ; param { string } line param { RouterData } router param { string } path return { string } const findRouterRequire = ( line , router , path ) : string => { let routerPath = '' ; const REQUIRE_PATTERN = new RegExp ( `${ router . importName }\\s*=\\s*require\\(\\s*['"\`](\\S+)['"\`]\\)` ) ; const REQUIRE_FOUND = line . match ( REQUIRE_PATTERN ) ; if ( REQUIRE_FOUND ) { routerPath = resolvePath ( pathUtil . join ( path , REQUIRE_FOUND [ 1 ] ) . replace ( /\\/g , '/' ) ) [ 0 ] ; } return routerPath ; } ; param { string } line param { RouterData } router param { File } file return { string } const searchLineForPath = ( line , router , file , supportFiles ) : string => { let routerPath = findRouterRequire ( line , router , file . path ) ; if ( routerPath !== '' ) return routerPath ; routerPath = findJoinRequire ( line , router , file . path ) ; if ( routerPath !== '' ) return routerPath ; routerPath = findRouterImport ( line , router , file . path ) ; if ( routerPath !== '' ) return routerPath ; routerPath = findRouterInit ( line , router , file . path ) ; if ( routerPath !== '' ) return routerPath . concat ( file . fileName ) ; routerPath = findPathRequire ( line , router , file . path , supportFiles ) ; return routerPath ; } ; param { File } file param { RouterData } router param { Map < string , File > } supportFiles return { string } export const findPath = ( file , router , supportFiles ) : string => { let routerPath = '' ; const LINES = file . contents . split ( NEW_LINE ) ; for ( const LINE of LINES ) { routerPath = searchLineForPath ( LINE , router , file , supportFiles ) ; if ( routerPath !== '' ) break ; } return routerPath ; } ; param router param file param supportFiles return export const findRouterPath = ( router , file , supportFiles ) : string => { let routerPath = '' ; const PATH_FOUND = router . importName . match ( REQUIRE_PATH ) ; routerPath = PATH_FOUND ? resolvePath ( pathUtil . join ( file . path , PATH_FOUND [ 1 ] ) . replace ( /\\/g , '/' ) ) [ 0 ] : findPath ( file , router , supportFiles ) ; return routerPath ; } ; param { string } line param { string } nextLine param { number } lineNum param { string } path param { string } baseRoute return { Route [ ] } const findMultiLineRoutes = ( line , nextLine , lineNum , path , baseRoute ) : Route [ ] => { const routes = [ ] ; const HAS_ROUTE = line . match ( MULTI_LINE_ROUTE ) ; if ( HAS_ROUTE ) { const ROUTE_FOUND = nextLine . match ( ROUTE_ENDPOINT ) ; if ( ROUTE_FOUND ) { let route = baseRoute + ROUTE_FOUND [ 1 ] ; while ( route . slice ( - 1 ) === '/' ) { route = route . slice ( 0 , Math . max ( 0 , route . length - 1 ) ) ; } routes . push ( { path , route , method : HAS_ROUTE [ 1 ] , startLine : lineNum + 1 , endLine : lineNum + 1 , } ) ; } } return routes ; } ; param { string } line param { number } lineNum param { string } path param { string } baseRoute return { Route [ ] } const checkLineForRoute = ( line , lineNum , path , baseRoute ) : Route [ ] => { const routes = [ ] ; const HAS_ROUTE = line . match ( EXPRESS_ROUTE ) ; if ( HAS_ROUTE ) { let route = baseRoute + HAS_ROUTE [ 2 ] ; while ( route . slice ( - 1 ) === '/' ) { route = route . slice ( 0 , Math . max ( 0 , route . length - 1 ) ) ; } routes . push ( { path , route , method : HAS_ROUTE [ 1 ] , startLine : lineNum + 1 , endLine : lineNum + 1 , } ) ; } return routes ; } ; param { string } contents param { string } path param { string } baseRoute return { Route [ ] } export const findRoutes = ( contents , path , baseRoute ) : Route [ ] => { let routes = [ ] ; const LINES = contents . split ( NEW_LINE ) ; for ( let i = 0 ; i < LINES . length ; i += 1 ) { routes = routes . concat ( checkLineForRoute ( LINES [ i ] , i , path , baseRoute ) ) ; routes = routes . concat ( findMultiLineRoutes ( LINES [ i ] , LINES [ i + 1 ] , i , path , baseRoute ) ) ; } return routes ; } ;