next-api-analyzer
Version:
Next.js API routes analyzer for security, performance, and maintainability
337 lines (319 loc) • 12.1 kB
TypeScript
import ts from 'typescript';
export { program } from './bin/api-analyzer.js';
import 'commander';
interface ApiRouteInfo {
path: string;
methods: HttpMethod[];
hasAuth: boolean;
authTypes: AuthType[];
queryParams: Parameter[];
pathParams: Parameter[];
bodyParams: Parameter[];
headers: string[];
responseStatuses: number[];
middlewares: string[];
description?: string;
riskLevel: RiskLevel;
hasRateLimit: boolean;
hasCors: boolean;
hasInputValidation: boolean;
dependencies: string[];
complexity: number;
lastModified: Date;
fileSize: number;
linesOfCode: number;
performanceScore: number;
}
interface Parameter {
name: string;
type: string;
required: boolean;
description?: string;
}
interface ApiAnalysisResult {
routes: ApiRouteInfo[];
summary: AnalysisSummary;
metadata: AnalysisMetadata;
recommendations: Recommendation[];
}
interface AnalysisSummary {
totalRoutes: number;
secureRoutes: number;
publicRoutes: number;
methodsBreakdown: Record<HttpMethod, number>;
statusCodeDistribution: Record<string, number>;
riskDistribution: Record<RiskLevel, number>;
securityScore: number;
performanceScore: number;
maintainabilityScore: number;
testCoverageScore: number;
}
interface AnalysisMetadata {
analyzedAt: Date;
version: string;
duration: number;
totalFiles: number;
totalLinesOfCode: number;
}
interface Recommendation {
id: string;
type: RecommendationType;
severity: Severity;
title: string;
description: string;
route?: string;
solution: string;
impact: string;
effort: Effort;
category: string;
tags: string[];
codeExample?: string;
fixExample?: string;
}
interface AnalyzerConfig {
apiDir: string;
outputDir: string;
includePatterns: string[];
excludePatterns: string[];
authPatterns: AuthPattern[];
middlewarePatterns: MiddlewarePattern[];
enableTrends: boolean;
enablePerformanceAnalysis: boolean;
enableSecurityAnalysis: boolean;
thresholds: QualityThresholds;
cache: CacheConfig;
parallel: boolean;
maxConcurrency: number;
}
interface AuthPattern {
name: string;
pattern: RegExp;
type: AuthType;
confidence: number;
}
interface MiddlewarePattern {
name: string;
pattern: RegExp;
category: string;
}
interface QualityThresholds {
security: number;
performance: number;
maintainability: number;
testCoverage: number;
complexity: number;
}
interface CacheConfig {
enabled: boolean;
ttl: number;
directory: string;
}
interface AnalysisContext {
config: AnalyzerConfig;
startTime: number;
processedFiles: number;
totalFiles: number;
errors: AnalysisError[];
}
interface AnalysisError {
file: string;
error: string;
severity: "warning" | "error";
}
interface AnalyzerPlugin {
name: string;
version: string;
analyze(route: ApiRouteInfo, content: string, context: AnalysisContext): Promise<PluginResult>;
}
interface PluginResult {
recommendations: Recommendation[];
metrics: Record<string, number>;
metadata: Record<string, any>;
}
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "HEAD" | "OPTIONS";
type RiskLevel = "LOW" | "MEDIUM" | "HIGH" | "CRITICAL";
type Severity = "LOW" | "MEDIUM" | "HIGH" | "CRITICAL";
type Effort = "LOW" | "MEDIUM" | "HIGH";
type RecommendationType = "SECURITY" | "PERFORMANCE" | "MAINTAINABILITY" | "TESTING" | "DOCUMENTATION";
type AuthType = "JWT" | "Bearer Token" | "API Key" | "Session" | "OAuth" | "NextAuth.js" | "Firebase Auth" | "Supabase Auth" | "Auth0" | "Passport";
declare class NextApiAnalyzer {
private config;
private routes;
private startTime;
constructor(config?: Partial<AnalyzerConfig>);
analyzeRoutes(): Promise<ApiAnalysisResult>;
private analyzeFile;
private parseRouteInfo;
private generateAnalysisResult;
generateReport(analysis: ApiAnalysisResult): string;
private isAppRouterFile;
private getRoutePath;
private extractMethods;
private detectAuth;
private extractAuthTypes;
private extractQueryParams;
private extractPathParams;
private extractBodyParams;
private extractHeaders;
private extractResponseStatuses;
private extractMiddlewares;
private extractDescription;
private detectRateLimit;
private detectCors;
private detectInputValidation;
private extractDependencies;
private generateRecommendations;
private calculateMethodsBreakdown;
private calculateStatusCodeDistribution;
private calculateRiskDistribution;
private calculateSecurityScore;
private calculatePerformanceScore;
private calculateMaintainabilityScore;
}
declare function analyzeApiRoutes(apiDir?: string): Promise<void>;
declare function withApiTracking(handler: any): (req: any, res: any) => Promise<void>;
declare class PluginManager {
private plugins;
loadPlugin(plugin: AnalyzerPlugin): Promise<void>;
runPlugins(route: ApiRouteInfo, content: string, context: AnalysisContext): Promise<PluginResult[]>;
getLoadedPlugins(): string[];
}
declare class OpenApiPlugin implements AnalyzerPlugin {
name: string;
version: string;
analyze(route: ApiRouteInfo, content: string): Promise<PluginResult>;
private hasOpenApiDocs;
}
declare class TestCoveragePlugin implements AnalyzerPlugin {
name: string;
version: string;
analyze(route: ApiRouteInfo): Promise<PluginResult>;
}
declare class CacheManager {
private memoryCache;
private config;
constructor(config: CacheConfig);
get<T>(key: string): Promise<T | null>;
set<T>(key: string, data: T, ttl?: number): Promise<void>;
generateKey(...parts: string[]): string;
private isValid;
private getDiskCache;
private setDiskCache;
private startCleanupTimer;
}
declare const DEFAULT_CONFIG: AnalyzerConfig;
declare function validateConfig(config: AnalyzerConfig): string[];
declare const defaultConfig_DEFAULT_CONFIG: typeof DEFAULT_CONFIG;
declare const defaultConfig_validateConfig: typeof validateConfig;
declare namespace defaultConfig {
export { defaultConfig_DEFAULT_CONFIG as DEFAULT_CONFIG, defaultConfig_validateConfig as validateConfig };
}
declare enum LogLevel {
DEBUG = 0,
INFO = 1,
WARN = 2,
ERROR = 3
}
interface LoggerConfig {
level: LogLevel;
colors: boolean;
prefix?: string;
}
declare class Logger {
private static instance;
private config;
static getInstance(): Logger;
configure(config: Partial<LoggerConfig>): void;
private shouldLog;
private formatMessage;
debug(message: string, ...args: any[]): void;
info(message: string, ...args: any[]): void;
success(message: string, ...args: any[]): void;
warn(message: string, ...args: any[]): void;
error(message: string, ...args: any[]): void;
progress(message: string): void;
clearProgress(): void;
separator(): void;
}
declare const logger: Logger;
type logger$1_LogLevel = LogLevel;
declare const logger$1_LogLevel: typeof LogLevel;
type logger$1_Logger = Logger;
declare const logger$1_Logger: typeof Logger;
type logger$1_LoggerConfig = LoggerConfig;
declare const logger$1_logger: typeof logger;
declare namespace logger$1 {
export { logger$1_LogLevel as LogLevel, logger$1_Logger as Logger, type logger$1_LoggerConfig as LoggerConfig, logger$1_logger as logger };
}
declare class FileUtils {
static findApiFiles(config: AnalyzerConfig): Promise<string[]>;
static isApiFile(filename: string): boolean;
static getFileStats(filePath: string): Promise<{
size: number;
lastModified: Date;
linesOfCode: number;
}>;
static ensureDirectoryExists(dirPath: string): Promise<void>;
static writeJsonFile(filePath: string, data: any): Promise<void>;
static readJsonFile<T>(filePath: string): Promise<T | null>;
static writeFile(filePath: string, content: string): Promise<void>;
static generateHash(content: string): string;
static fileExists(filePath: string): Promise<boolean>;
}
type fileUtils_FileUtils = FileUtils;
declare const fileUtils_FileUtils: typeof FileUtils;
declare namespace fileUtils {
export { fileUtils_FileUtils as FileUtils };
}
declare abstract class BaseAnalyzer {
protected static createRecommendation: (id: string, type: "SECURITY" | "PERFORMANCE" | "MAINTAINABILITY" | "TESTING" | "DOCUMENTATION", severity: Severity, title: string, description: string, route: string, solution: string, impact: string, effort: "LOW" | "MEDIUM" | "HIGH", category: string, tags?: string[], codeExample?: string, fixExample?: string) => Recommendation;
protected static extractMethods(content: string, sourceFile: ts.SourceFile, isAppRouter: boolean): string[];
protected static extractParams(content: string, pattern: RegExp): string[];
protected static calculateComplexity(sourceFile: ts.SourceFile): number;
}
declare class SecurityAnalyzer extends BaseAnalyzer {
private static readonly VULNERABILITIES;
static analyzeRoute(route: ApiRouteInfo, content: string): {
riskLevel: RiskLevel;
recommendations: Recommendation[];
securityScore: number;
vulnerabilities: string[];
};
private static isSensitiveRoute;
private static getVulnerabilitySolution;
private static getVulnerabilityImpact;
}
type securityAnalyzer_SecurityAnalyzer = SecurityAnalyzer;
declare const securityAnalyzer_SecurityAnalyzer: typeof SecurityAnalyzer;
declare namespace securityAnalyzer {
export { securityAnalyzer_SecurityAnalyzer as SecurityAnalyzer };
}
declare class PerformanceAnalyzer extends BaseAnalyzer {
static analyzeRoute(route: ApiRouteInfo, content: string, sourceFile: ts.SourceFile): {
performanceScore: number;
recommendations: Recommendation[];
complexity: number;
};
private static getIssueScore;
private static getIssueSeverity;
private static getIssueTitle;
private static getIssueDescription;
private static getIssueSolution;
private static getIssueImpact;
}
type performanceAnalyzer_PerformanceAnalyzer = PerformanceAnalyzer;
declare const performanceAnalyzer_PerformanceAnalyzer: typeof PerformanceAnalyzer;
declare namespace performanceAnalyzer {
export { performanceAnalyzer_PerformanceAnalyzer as PerformanceAnalyzer };
}
declare const VERSION = "3.1.0";
declare const ENTERPRISE_CONFIG: Partial<AnalyzerConfig>;
declare const SECURITY_FOCUSED_CONFIG: Partial<AnalyzerConfig>;
declare const PERFORMANCE_FOCUSED_CONFIG: Partial<AnalyzerConfig>;
declare function createSecurityAnalyzer(config?: Partial<AnalyzerConfig>): NextApiAnalyzer;
declare function createPerformanceAnalyzer(config?: Partial<AnalyzerConfig>): NextApiAnalyzer;
declare function createEnterpriseAnalyzer(config?: Partial<AnalyzerConfig>): NextApiAnalyzer;
declare function quickSecurityAudit(apiDir?: string): Promise<ApiAnalysisResult>;
declare function quickPerformanceAudit(apiDir?: string): Promise<ApiAnalysisResult>;
declare function quickEnterpriseAudit(apiDir?: string): Promise<ApiAnalysisResult>;
export { type AnalysisContext, type AnalysisError, type AnalysisMetadata, type AnalysisSummary, type AnalyzerConfig, type AnalyzerPlugin, type ApiAnalysisResult, type ApiRouteInfo, type AuthPattern, type AuthType, type CacheConfig, CacheManager, ENTERPRISE_CONFIG, type Effort, type HttpMethod, type MiddlewarePattern, NextApiAnalyzer, OpenApiPlugin, PERFORMANCE_FOCUSED_CONFIG, type Parameter, PluginManager, type PluginResult, type QualityThresholds, type Recommendation, type RecommendationType, type RiskLevel, SECURITY_FOCUSED_CONFIG, type Severity, TestCoveragePlugin, VERSION, analyzeApiRoutes, createEnterpriseAnalyzer, createPerformanceAnalyzer, createSecurityAnalyzer, defaultConfig, fileUtils, logger$1 as logger, performanceAnalyzer, quickEnterpriseAudit, quickPerformanceAudit, quickSecurityAudit, securityAnalyzer, withApiTracking };