"use strict";
/**
 * Imported Auth Detector
 *
 * Detects auth middleware/helpers imported from other files to avoid
 * false positives on routes that are actually protected via imports.
 *
 * Example: A route file that does `import { authMiddleware } from '@/lib/auth'`
 * and wraps handlers with it should not be flagged as "missing auth".
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.extractImports = extractImports;
exports.detectImportedAuthUsage = detectImportedAuthUsage;
exports.buildFileAuthImports = buildFileAuthImports;
exports.fileUsesImportedAuth = fileUsesImportedAuth;
// ============================================================================
// Patterns
// ============================================================================
/**
 * Patterns that indicate auth-related imports by name
 */
const AUTH_NAME_PATTERNS = [
    /auth/i,
    /middleware/i,
    /protect/i,
    /guard/i,
    /session/i,
    /verify/i,
    /secure/i,
    /jwt/i,
    /token/i,
];
/**
 * Specific auth import names commonly used
 */
const KNOWN_AUTH_IMPORTS = new Set([
    // Next.js / NextAuth
    'auth',
    'getServerSession',
    'getSession',
    'withAuth',
    'getToken',
    'NextAuth',
    'NextAuthOptions',
    // Clerk
    'auth',
    'currentUser',
    'clerkMiddleware',
    'getAuth',
    'SignedIn',
    'SignedOut',
    // Auth0
    'withPageAuthRequired',
    'withApiAuthRequired',
    'getSession',
    'getAccessToken',
    // Custom auth patterns
    'authMiddleware',
    'requireAuth',
    'requireAuthentication',
    'checkAuth',
    'verifyAuth',
    'protectRoute',
    'withAuthentication',
    'authenticated',
    'getCurrentUser',
    'getCurrentUserId',
    'getUser',
    'getUserId',
]);
/**
 * Patterns indicating auth-related import paths
 */
const AUTH_PATH_PATTERNS = [
    /\/auth\//i,
    /\/middleware/i,
    /\/lib\/auth/i,
    /\/utils\/auth/i,
    /\/helpers\/auth/i,
    /next-auth/i,
    /@clerk/i,
    /@auth0/i,
    /lucia/i,
];
// ============================================================================
// Import Extraction
// ============================================================================
/**
 * Extract all imports from a file's content
 */
function extractImports(content) {
    const imports = [];
    // ES6 named imports: import { x, y } from 'path'
    const es6NamedPattern = /import\s+\{([^}]+)\}\s+from\s+['"]([^'"]+)['"]/g;
    let match;
    while ((match = es6NamedPattern.exec(content)) !== null) {
        const names = match[1]
            .split(',')
            .map(n => n.trim().split(/\s+as\s+/)[0].trim()) // Handle 'x as y'
            .filter(n => n.length > 0);
        const importPath = match[2];
        const isAuthRelated = isAuthRelatedImport(names, importPath);
        imports.push({
            importPath,
            importedNames: names,
            isAuthRelated,
        });
    }
    // ES6 default imports: import x from 'path'
    const defaultPattern = /import\s+(\w+)\s+from\s+['"]([^'"]+)['"]/g;
    while ((match = defaultPattern.exec(content)) !== null) {
        const name = match[1];
        const importPath = match[2];
        // Skip if already captured as named import
        if (imports.some(imp => imp.importPath === importPath))
            continue;
        const isAuthRelated = isAuthRelatedImport([name], importPath);
        imports.push({
            importPath,
            importedNames: [name],
            isAuthRelated,
        });
    }
    // CommonJS require: const { x } = require('path')
    const requireDestructurePattern = /(?:const|let|var)\s+\{([^}]+)\}\s*=\s*require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
    while ((match = requireDestructurePattern.exec(content)) !== null) {
        const names = match[1]
            .split(',')
            .map(n => n.trim().split(/\s*:\s*/)[0].trim()) // Handle 'x: y' renaming
            .filter(n => n.length > 0);
        const importPath = match[2];
        const isAuthRelated = isAuthRelatedImport(names, importPath);
        imports.push({
            importPath,
            importedNames: names,
            isAuthRelated,
        });
    }
    // CommonJS require: const x = require('path')
    const requireDefaultPattern = /(?:const|let|var)\s+(\w+)\s*=\s*require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
    while ((match = requireDefaultPattern.exec(content)) !== null) {
        const name = match[1];
        const importPath = match[2];
        // Skip if already captured
        if (imports.some(imp => imp.importPath === importPath))
            continue;
        const isAuthRelated = isAuthRelatedImport([name], importPath);
        imports.push({
            importPath,
            importedNames: [name],
            isAuthRelated,
        });
    }
    return imports;
}
/**
 * Check if an import is auth-related based on names and path
 */
function isAuthRelatedImport(names, importPath) {
    // Check if path is auth-related
    if (AUTH_PATH_PATTERNS.some(p => p.test(importPath))) {
        return true;
    }
    // Check if any imported name is auth-related
    for (const name of names) {
        // Known auth imports
        if (KNOWN_AUTH_IMPORTS.has(name)) {
            return true;
        }
        // Pattern-based detection
        if (AUTH_NAME_PATTERNS.some(p => p.test(name))) {
            return true;
        }
    }
    return false;
}
// ============================================================================
// Auth Usage Detection
// ============================================================================
/**
 * Check if imported auth is actually used to protect routes/handlers
 */
function detectImportedAuthUsage(content, authImports) {
    if (authImports.length === 0)
        return false;
    const authNames = authImports.flatMap(imp => imp.importedNames);
    for (const name of authNames) {
        // Pattern 1: Handler wrapping - export const GET = authMiddleware(...)
        const wrapperPattern = new RegExp(`(?:export\\s+(?:const|function)\\s+(?:GET|POST|PUT|PATCH|DELETE|handler)\\s*=\\s*${escapeRegex(name)}\\s*\\()` +
            `|(?:${escapeRegex(name)}\\s*\\(\\s*(?:async\\s+)?(?:function|\\())`);
        if (wrapperPattern.test(content)) {
            return true;
        }
        // Pattern 2: Middleware chain - app.use(authMiddleware)
        const middlewareChainPattern = new RegExp(`\\.(?:use|all|get|post|put|patch|delete)\\s*\\([^)]*${escapeRegex(name)}`);
        if (middlewareChainPattern.test(content)) {
            return true;
        }
        // Pattern 3: Express/Fastify route with middleware - router.get('/', requireAuth, handler)
        const routeMiddlewarePattern = new RegExp(`\\.(?:get|post|put|patch|delete)\\s*\\([^,]+,\\s*${escapeRegex(name)}`);
        if (routeMiddlewarePattern.test(content)) {
            return true;
        }
        // Pattern 4: HOC pattern - withAuth(Component)
        const hocPattern = new RegExp(`${escapeRegex(name)}\\s*\\(\\s*\\w+\\s*\\)`);
        if (hocPattern.test(content)) {
            return true;
        }
        // Pattern 5: Auth function call at top of handler - const session = await auth()
        const authCallPattern = new RegExp(`(?:await\\s+)?${escapeRegex(name)}\\s*\\(\\s*\\)` +
            `|${escapeRegex(name)}\\s*\\(\\s*(?:req|request|ctx|context)\\s*[,)]`);
        if (authCallPattern.test(content)) {
            return true;
        }
    }
    return false;
}
/**
 * Escape special regex characters in a string
 */
function escapeRegex(str) {
    return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
// ============================================================================
// Registry Builder
// ============================================================================
/**
 * Build a registry of files and their auth imports
 */
function buildFileAuthImports(files) {
    const registry = new Map();
    for (const file of files) {
        const allImports = extractImports(file.content);
        const authImports = allImports.filter(imp => imp.isAuthRelated);
        const usesImportedAuth = authImports.length > 0 &&
            detectImportedAuthUsage(file.content, authImports);
        registry.set(file.path, {
            filePath: file.path,
            imports: authImports,
            usesImportedAuth,
        });
    }
    return registry;
}
/**
 * Check if a specific file uses imported auth protection
 */
function fileUsesImportedAuth(filePath, registry) {
    return registry.get(filePath)?.usesImportedAuth ?? false;
}
//# sourceMappingURL=imported-auth-detector.js.map