class Analyzer::Javascript::RouterMountScanner

Overview

RouterMountScanner handles the two-pass scanning process for Express router mounts. It scans JavaScript/TypeScript files to discover router mount patterns like: app.use('/api', userRouter) router.use('/v1', require('./routes')) and stores the prefix information in CodeLocator for cross-file resolution.

Included Modules

Defined in:

analyzer/analyzers/javascript/express/router_mount_scanner.cr

Constant Summary

HONO_ROUTE_MOUNT_RE = /\.route\s*\(\s*['"]([^'"]+)['"]\s*,\s*(\w+)\s*\)/

Hono <chain>.route('/prefix', ChildApp) mounts. Registers the prefix on the child's file when ChildApp is an imported router, regardless of (or in the absence of) a named caller.

JS_TO_TS_EXT = {".js" => [".ts", ".tsx"], ".jsx" => [".tsx"], ".mjs" => [".mts"], ".cjs" => [".cts"]}

TypeScript ESM (moduleResolution: NodeNext) imports a sibling .ts source through a .js-family specifier. Map each JS extension to the TS source extension(s) it can stand in for, so resolve_require_path can fall back to the real on-disk file when the literal path is absent.

MOUNT_ARRAY_RES = MOUNT_CALL_NAMES.map do |c| {c, /(\w+)\.#{c}\s*\(\s*\[([^\]]+)\]\s*,\s*/m} end.to_h
MOUNT_BACKTICK_RES = MOUNT_CALL_NAMES.map do |c| {c, /(\w+)\.#{c}\s*\(\s*`([^`$]+)`\s*,\s*/} end.to_h
MOUNT_CALL_NAMES = ["use", "route"] of ::String

Mount-call verbs scanned for literal prefixes (.use('/p', r) / .route('/p', app)). Compiled once per verb — interpolated regex literals would otherwise be rebuilt (full PCRE2 compile) on every scan_literal_mount_calls invocation.

MOUNT_IDENT_RES = MOUNT_CALL_NAMES.map do |c| {c, /(\w+)\.#{c}\s*\(\s*(\w+)\s*,\s*/} end.to_h
MOUNT_STRING_RES = MOUNT_CALL_NAMES.map do |c| {c, /(\w+)\.#{c}\s*\(\s*['"]([^'"]+)['"]\s*,\s*/} end.to_h

Constructors

Instance Method Summary

Class methods inherited from module Analyzer::Javascript::ExpressConstants

file_key(file_path : String) : String file_key, function_key(file_path : String, function_name : String) : String function_key

Constructor Detail

def self.new(all_files : Array(String), base_paths : Array(String), base_path : String, logger : NoirLogger) #

[View source]

Instance Method Detail

def scan #

Main entry point: scan all files for router mount patterns


[View source]