gateops-core 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../package.json","../src/config.ts","../src/db/schema.ts","../src/db/index.ts","../src/buffer/disk.ts","../src/buffer/index.ts","../src/sanitizer.ts","../src/middleware.ts","../src/routes.ts","../src/scanner.ts","../src/sync.ts","../src/index.ts"],"names":["exports","fs","path2","db","axios","uuidv4","path","and","eq"],"mappings":"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","file":"index.mjs","sourcesContent":["{\n \"name\": \"gateops-core\",\n \"version\": \"0.1.0\",\n \"description\": \"Lightweight API observability SDK for Express.js - Zero-config, privacy-first traffic monitoring\",\n \"main\": \"dist/index.js\",\n \"module\": \"dist/index.mjs\",\n \"types\": \"dist/index.d.ts\",\n \"bin\": {\n \"gateops-init\": \"dist/bin/gateops-init.js\"\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"test\": \"vitest\",\n \"test:run\": \"vitest run\",\n \"lint\": \"eslint src --ext .ts\",\n \"format\": \"prettier --write src\",\n \"prepublishOnly\": \"npm run build\"\n },\n \"keywords\": [\n \"api\",\n \"observability\",\n \"monitoring\",\n \"express\",\n \"middleware\",\n \"logging\",\n \"debugging\",\n \"documentation\",\n \"swagger\",\n \"openapi\"\n ],\n \"author\": \"GateOps\",\n \"license\": \"MIT\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/gateops/gateops-core\"\n },\n \"engines\": {\n \"node\": \">=18.0.0\"\n },\n \"peerDependencies\": {\n \"express\": \"^4.18.0 || ^5.0.0\"\n },\n \"dependencies\": {\n \"axios\": \"^1.6.0\",\n \"better-sqlite3\": \"^11.0.0\",\n \"chalk\": \"^4.1.2\",\n \"commander\": \"^12.0.0\",\n \"drizzle-orm\": \"^0.29.0\",\n \"inquirer\": \"^8.2.6\",\n \"uuid\": \"^9.0.0\",\n \"zod\": \"^3.22.0\"\n },\n \"devDependencies\": {\n \"@types/better-sqlite3\": \"^7.6.8\",\n \"@types/express\": \"^4.17.21\",\n \"@types/inquirer\": \"^8.2.10\",\n \"@types/node\": \"^20.10.0\",\n \"@types/uuid\": \"^9.0.7\",\n \"drizzle-kit\": \"^0.20.0\",\n \"eslint\": \"^8.56.0\",\n \"express\": \"^4.18.2\",\n \"prettier\": \"^3.2.0\",\n \"tsup\": \"^8.0.0\",\n \"typescript\": \"^5.3.0\",\n \"vitest\": \"^1.2.0\"\n }\n}\n","/**\n * GateOps SDK Configuration\n * \n * Panel API endpoints are centralized here for easy modification.\n * Change these values if the Panel API structure changes.\n */\n\n// Panel base URL - change this if hosting changes\nexport const PANEL_BASE_URL = process.env.GATEOPS_PANEL_URL || 'https://gateops.sleeksoulsmedia.com';\n\n/**\n * Panel API Endpoints\n * \n * Modify these paths if the Panel API structure changes.\n * All paths are relative to PANEL_BASE_URL.\n */\nexport const PANEL_ENDPOINTS = {\n // Verify API key during initialization\n VERIFY: '/api/sdk/verify',\n\n // Send batched logs to Panel\n LOGS: '/api/sdk/logs',\n\n // Fetch remote configuration (optional)\n CONFIG: '/api/sdk/config',\n\n // Send discovered endpoints/routes\n ENDPOINTS: '/api/sdk/endpoints',\n\n // Heartbeat/health check\n HEARTBEAT: '/api/sdk/heartbeat'\n} as const;\n\n/**\n * SDK Default Configuration\n */\nexport const SDK_DEFAULTS = {\n // Buffer settings\n BUFFER_MAX_SIZE: 50, // Flush when buffer reaches this size\n BUFFER_FLUSH_INTERVAL: 10000, // Flush every 10 seconds (ms)\n\n // Payload limits\n MAX_BODY_SIZE: 10240, // 10KB max for req/res bodies\n\n // Log retention\n LOG_TTL_DAYS: 15, // Auto-cleanup logs older than 15 days\n\n // Retry settings\n MAX_RETRY_ATTEMPTS: 3,\n RETRY_DELAY_BASE: 1000, // Base delay for exponential backoff (ms)\n\n // Database\n DEFAULT_DB_PATH: '.gateops/data.sqlite',\n BUFFER_FILE_PATH: '.gateops/buffer.json',\n\n // Route prefix for exposed endpoints\n ROUTE_PREFIX: '/.well-known/gateops'\n} as const;\n\n/**\n * Sensitive field patterns for sanitization\n */\nexport const SENSITIVE_PATTERNS = {\n // Field names to redact (case-insensitive)\n FIELD_NAMES: [\n 'password',\n 'passwd',\n 'secret',\n 'token',\n 'apikey',\n 'api_key',\n 'api-key',\n 'authorization',\n 'auth',\n 'bearer',\n 'credential',\n 'private',\n 'ssn',\n 'credit_card',\n 'creditcard',\n 'card_number',\n 'cvv',\n 'pin'\n ],\n\n // Regex patterns for value-based detection\n VALUE_PATTERNS: {\n // Credit card (basic pattern)\n CREDIT_CARD: /\\b\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}\\b/g,\n // SSN pattern\n SSN: /\\b\\d{3}[-]?\\d{2}[-]?\\d{4}\\b/g\n },\n\n // Replacement text\n REDACTED: '[REDACTED]',\n MASKED_CARD: '****-****-****-****'\n} as const;\n\n/**\n * Get full Panel endpoint URL\n */\nexport function getPanelUrl(endpoint: keyof typeof PANEL_ENDPOINTS): string {\n return `${PANEL_BASE_URL}${PANEL_ENDPOINTS[endpoint]}`;\n}\n\nexport type PanelEndpointKey = keyof typeof PANEL_ENDPOINTS;\n","import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';\n\n/**\n * Traffic logs table - stores all captured API requests/responses\n * \n * TTL: 15 days (cleanup handled by SDK)\n */\nexport const trafficLogs = sqliteTable('gateops_traffic_logs', {\n id: integer('id').primaryKey({ autoIncrement: true }),\n\n // Unique identifier for request tracing\n trace_id: text('trace_id').notNull(),\n\n // Request info\n endpoint: text('endpoint').notNull(),\n method: text('method').notNull(),\n status: integer('status').notNull(),\n duration_ms: integer('duration_ms').notNull(),\n\n // Headers (JSON strings)\n req_headers: text('req_headers'),\n res_headers: text('res_headers'),\n\n // Bodies (JSON strings, sanitized, max 10KB each)\n req_body: text('req_body'),\n res_body: text('res_body'),\n\n // Additional context\n query_params: text('query_params'),\n ip_address: text('ip_address'),\n user_agent: text('user_agent'),\n\n // Timestamp (stored as Unix timestamp)\n created_at: integer('created_at', { mode: 'timestamp' }).notNull()\n});\n\n/**\n * Endpoints table - stores discovered routes for documentation\n * \n * Updated on each app startup + when new routes are hit\n */\nexport const endpoints = sqliteTable('gateops_endpoints', {\n id: integer('id').primaryKey({ autoIncrement: true }),\n\n // Route identification (unique constraint on path + method)\n path: text('path').notNull(),\n method: text('method').notNull(),\n\n // Inferred request/response schema (JSON string)\n // Deep inference captures nested structures\n detected_schema: text('detected_schema'),\n\n // List of middleware names (JSON array)\n middleware_names: text('middleware_names'),\n\n // Last time this endpoint was hit\n last_seen: integer('last_seen', { mode: 'timestamp' }).notNull()\n});\n\n/**\n * Config table - key/value store for SDK configuration\n * \n * Used for storing latency rules, custom settings, etc.\n */\nexport const config = sqliteTable('gateops_config', {\n // Unique key name\n key: text('key').primaryKey(),\n\n // Value as JSON string\n value: text('value').notNull(),\n\n // When this config was last updated\n updated_at: integer('updated_at', { mode: 'timestamp' })\n});\n\n// Export table types for Drizzle\nexport type TrafficLogInsert = typeof trafficLogs.$inferInsert;\nexport type TrafficLogSelect = typeof trafficLogs.$inferSelect;\n\nexport type EndpointInsert = typeof endpoints.$inferInsert;\nexport type EndpointSelect = typeof endpoints.$inferSelect;\n\nexport type ConfigInsert = typeof config.$inferInsert;\nexport type ConfigSelect = typeof config.$inferSelect;\n","import Database from 'better-sqlite3';\nimport { drizzle, BetterSQLite3Database } from 'drizzle-orm/better-sqlite3';\nimport { sql } from 'drizzle-orm';\nimport * as schema from './schema';\nimport { SDK_DEFAULTS } from '../config';\nimport * as fs from 'fs';\nimport * as path from 'path';\n\nlet db: BetterSQLite3Database<typeof schema> | null = null;\nlet sqliteDb: Database.Database | null = null;\n\n/**\n * Get or create the database connection\n */\nexport function getDatabase(dbPath?: string): BetterSQLite3Database<typeof schema> {\n if (db) {\n return db;\n }\n\n const resolvedPath = dbPath || process.env.GATEOPS_DB_PATH || SDK_DEFAULTS.DEFAULT_DB_PATH;\n const absolutePath = path.isAbsolute(resolvedPath)\n ? resolvedPath\n : path.join(process.cwd(), resolvedPath);\n\n // Ensure directory exists\n const dir = path.dirname(absolutePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n // Create SQLite connection\n sqliteDb = new Database(absolutePath);\n\n // Enable WAL mode for better concurrent performance\n sqliteDb.pragma('journal_mode = WAL');\n\n // Create Drizzle instance\n db = drizzle(sqliteDb, { schema });\n\n return db;\n}\n\n/**\n * Initialize database schema (create tables if not exist)\n */\nexport function initializeSchema(database?: BetterSQLite3Database<typeof schema>): void {\n const targetDb = database || getDatabase();\n\n // Create traffic_logs table\n targetDb.run(sql`\n CREATE TABLE IF NOT EXISTS gateops_traffic_logs (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n trace_id TEXT NOT NULL,\n endpoint TEXT NOT NULL,\n method TEXT NOT NULL,\n status INTEGER NOT NULL,\n duration_ms INTEGER NOT NULL,\n req_headers TEXT,\n res_headers TEXT,\n req_body TEXT,\n res_body TEXT,\n query_params TEXT,\n ip_address TEXT,\n user_agent TEXT,\n created_at INTEGER NOT NULL\n )\n `);\n\n // Create indexes for common queries\n targetDb.run(sql`\n CREATE INDEX IF NOT EXISTS idx_traffic_logs_created_at \n ON gateops_traffic_logs(created_at)\n `);\n\n targetDb.run(sql`\n CREATE INDEX IF NOT EXISTS idx_traffic_logs_endpoint \n ON gateops_traffic_logs(endpoint, method)\n `);\n\n targetDb.run(sql`\n CREATE INDEX IF NOT EXISTS idx_traffic_logs_status \n ON gateops_traffic_logs(status)\n `);\n\n // Create endpoints table\n targetDb.run(sql`\n CREATE TABLE IF NOT EXISTS gateops_endpoints (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n path TEXT NOT NULL,\n method TEXT NOT NULL,\n detected_schema TEXT,\n middleware_names TEXT,\n last_seen INTEGER NOT NULL,\n UNIQUE(path, method)\n )\n `);\n\n // Create config table\n targetDb.run(sql`\n CREATE TABLE IF NOT EXISTS gateops_config (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL,\n updated_at INTEGER\n )\n `);\n}\n\n/**\n * Close database connection\n */\nexport function closeDatabase(): void {\n if (sqliteDb) {\n sqliteDb.close();\n sqliteDb = null;\n db = null;\n }\n}\n\n/**\n * Clean up old logs based on TTL\n */\nexport function cleanupOldLogs(ttlDays: number = SDK_DEFAULTS.LOG_TTL_DAYS): number {\n const database = getDatabase();\n const cutoffDate = new Date();\n cutoffDate.setDate(cutoffDate.getDate() - ttlDays);\n\n const result = database.run(sql`\n DELETE FROM gateops_traffic_logs \n WHERE created_at < ${Math.floor(cutoffDate.getTime() / 1000)}\n `);\n\n return result.changes;\n}\n\n// Re-export schema\nexport * from './schema';\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport { SDK_DEFAULTS } from '../config';\nimport { TrafficLog, BufferState } from '../types';\n\nconst BUFFER_VERSION = '1.0.0';\n\n/**\n * Get the buffer file path\n */\nfunction getBufferFilePath(): string {\n return path.join(process.cwd(), SDK_DEFAULTS.BUFFER_FILE_PATH);\n}\n\n/**\n * Save buffer to disk for crash recovery\n */\nexport function saveToDisk(logs: TrafficLog[]): boolean {\n if (logs.length === 0) {\n return true;\n }\n\n try {\n const filePath = getBufferFilePath();\n const dir = path.dirname(filePath);\n\n // Ensure directory exists\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n const state: BufferState = {\n logs,\n savedAt: new Date().toISOString(),\n version: BUFFER_VERSION\n };\n\n fs.writeFileSync(filePath, JSON.stringify(state, null, 2), 'utf-8');\n return true;\n } catch (error) {\n console.error('[GateOps] Failed to save buffer to disk:', error);\n return false;\n }\n}\n\n/**\n * Load buffer from disk (for crash recovery)\n */\nexport function loadFromDisk(): TrafficLog[] {\n try {\n const filePath = getBufferFilePath();\n\n if (!fs.existsSync(filePath)) {\n return [];\n }\n\n const content = fs.readFileSync(filePath, 'utf-8');\n const state: BufferState = JSON.parse(content);\n\n // Validate version compatibility\n if (state.version !== BUFFER_VERSION) {\n console.warn('[GateOps] Buffer file version mismatch, skipping recovery');\n clearDiskBuffer();\n return [];\n }\n\n // Convert date strings back to Date objects\n const logs = state.logs.map(log => ({\n ...log,\n created_at: new Date(log.created_at)\n }));\n\n console.log(`[GateOps] Recovered ${logs.length} logs from disk buffer`);\n return logs;\n } catch (error) {\n console.error('[GateOps] Failed to load buffer from disk:', error);\n return [];\n }\n}\n\n/**\n * Clear the disk buffer file\n */\nexport function clearDiskBuffer(): boolean {\n try {\n const filePath = getBufferFilePath();\n\n if (fs.existsSync(filePath)) {\n fs.unlinkSync(filePath);\n }\n\n return true;\n } catch (error) {\n console.error('[GateOps] Failed to clear disk buffer:', error);\n return false;\n }\n}\n\n/**\n * Check if a disk buffer exists\n */\nexport function hasDiskBuffer(): boolean {\n return fs.existsSync(getBufferFilePath());\n}\n","import { TrafficLog } from '../types';\nimport { SDK_DEFAULTS, getPanelUrl } from '../config';\nimport { getDatabase, trafficLogs } from '../db';\nimport { saveToDisk, loadFromDisk, clearDiskBuffer, hasDiskBuffer } from './disk';\nimport axios from 'axios';\n\n/**\n * Buffer Manager - handles in-memory buffering with disk overflow\n * \n * Features:\n * - In-memory buffer with configurable size\n * - Auto-flush on size threshold or interval\n * - Dual write: local DB + Panel API\n * - Disk persistence for crash recovery\n */\nclass BufferManager {\n private buffer: TrafficLog[] = [];\n private flushInterval: NodeJS.Timeout | null = null;\n private isInitialized = false;\n private isFlushing = false;\n\n private maxSize: number;\n private intervalMs: number;\n private localOnly: boolean;\n private username: string;\n private apiKey: string;\n\n constructor() {\n this.maxSize = SDK_DEFAULTS.BUFFER_MAX_SIZE;\n this.intervalMs = SDK_DEFAULTS.BUFFER_FLUSH_INTERVAL;\n this.localOnly = false;\n this.username = '';\n this.apiKey = '';\n }\n\n /**\n * Initialize the buffer manager\n */\n initialize(options: {\n maxSize?: number;\n intervalMs?: number;\n localOnly?: boolean;\n username?: string;\n apiKey?: string;\n } = {}): void {\n if (this.isInitialized) {\n return;\n }\n\n this.maxSize = options.maxSize || SDK_DEFAULTS.BUFFER_MAX_SIZE;\n this.intervalMs = options.intervalMs || SDK_DEFAULTS.BUFFER_FLUSH_INTERVAL;\n this.localOnly = options.localOnly || false;\n this.username = options.username || process.env.GATEOPS_USERNAME || '';\n this.apiKey = options.apiKey || process.env.GATEOPS_API_KEY || '';\n\n // Recover from disk if needed\n this.recoverFromDisk();\n\n // Start flush interval\n this.startFlushInterval();\n\n // Register shutdown handlers\n this.registerShutdownHandlers();\n\n this.isInitialized = true;\n }\n\n /**\n * Push a log entry to the buffer\n */\n push(log: TrafficLog): void {\n this.buffer.push(log);\n\n // Check if we need to flush\n if (this.buffer.length >= this.maxSize) {\n this.flush();\n }\n }\n\n /**\n * Flush the buffer to database and Panel\n */\n async flush(): Promise<void> {\n if (this.isFlushing || this.buffer.length === 0) {\n return;\n }\n\n this.isFlushing = true;\n\n // Take current buffer and reset\n const logsToFlush = [...this.buffer];\n this.buffer = [];\n\n try {\n // Write to local database\n await this.writeToDatabase(logsToFlush);\n\n // Send to Panel (if not local-only mode)\n if (!this.localOnly && this.username && this.apiKey) {\n await this.sendToPanel(logsToFlush);\n }\n\n // Clear disk buffer on successful flush\n clearDiskBuffer();\n } catch (error) {\n console.error('[GateOps] Flush failed:', error);\n\n // Put logs back in buffer for retry\n this.buffer = [...logsToFlush, ...this.buffer];\n\n // Save to disk in case of crash\n saveToDisk(this.buffer);\n } finally {\n this.isFlushing = false;\n }\n }\n\n /**\n * Write logs to local SQLite database\n */\n private async writeToDatabase(logs: TrafficLog[]): Promise<void> {\n const db = getDatabase();\n\n for (const log of logs) {\n await db.insert(trafficLogs).values({\n trace_id: log.trace_id,\n endpoint: log.endpoint,\n method: log.method,\n status: log.status,\n duration_ms: log.duration_ms,\n req_headers: log.req_headers,\n res_headers: log.res_headers,\n req_body: log.req_body,\n res_body: log.res_body,\n query_params: log.query_params,\n ip_address: log.ip_address,\n user_agent: log.user_agent,\n created_at: log.created_at\n });\n }\n }\n\n /**\n * Send logs to Panel API\n */\n private async sendToPanel(logs: TrafficLog[]): Promise<void> {\n const url = getPanelUrl('LOGS');\n\n try {\n await axios.post(url, {\n logs: logs.map(log => ({\n ...log,\n created_at: log.created_at.toISOString()\n }))\n }, {\n headers: {\n 'Content-Type': 'application/json',\n 'x-gateops-username': this.username,\n 'x-gateops-api-key': this.apiKey\n },\n timeout: 10000 // 10 second timeout\n });\n } catch (error) {\n // Log but don't throw - local DB write is the priority\n console.warn('[GateOps] Failed to send logs to Panel:',\n axios.isAxiosError(error) ? error.message : error\n );\n }\n }\n\n /**\n * Recover logs from disk buffer\n */\n private recoverFromDisk(): void {\n if (hasDiskBuffer()) {\n const recoveredLogs = loadFromDisk();\n if (recoveredLogs.length > 0) {\n this.buffer = [...recoveredLogs, ...this.buffer];\n clearDiskBuffer();\n\n // Trigger flush of recovered logs\n setTimeout(() => this.flush(), 1000);\n }\n }\n }\n\n /**\n * Start the periodic flush interval\n */\n private startFlushInterval(): void {\n if (this.flushInterval) {\n clearInterval(this.flushInterval);\n }\n\n this.flushInterval = setInterval(() => {\n this.flush();\n }, this.intervalMs);\n\n // Don't keep Node.js alive just for this\n this.flushInterval.unref();\n }\n\n /**\n * Register handlers for graceful shutdown\n */\n private registerShutdownHandlers(): void {\n const gracefulShutdown = () => {\n // Save buffer to disk before exit\n if (this.buffer.length > 0) {\n saveToDisk(this.buffer);\n }\n\n // Try to flush synchronously (best effort)\n this.flush();\n\n // Clear interval\n if (this.flushInterval) {\n clearInterval(this.flushInterval);\n }\n };\n\n process.on('SIGINT', gracefulShutdown);\n process.on('SIGTERM', gracefulShutdown);\n process.on('beforeExit', gracefulShutdown);\n\n // Handle uncaught exceptions - save to disk\n process.on('uncaughtException', (error) => {\n console.error('[GateOps] Uncaught exception, saving buffer to disk:', error);\n saveToDisk(this.buffer);\n });\n }\n\n /**\n * Get current buffer size\n */\n getSize(): number {\n return this.buffer.length;\n }\n\n /**\n * Shutdown the buffer manager\n */\n shutdown(): void {\n if (this.flushInterval) {\n clearInterval(this.flushInterval);\n this.flushInterval = null;\n }\n\n // Final flush\n if (this.buffer.length > 0) {\n saveToDisk(this.buffer);\n }\n\n this.isInitialized = false;\n }\n}\n\n// Export singleton instance\nexport const buffer = new BufferManager();\n\n// Re-export disk utilities\nexport { saveToDisk, loadFromDisk, clearDiskBuffer, hasDiskBuffer } from './disk';\n","import { SENSITIVE_PATTERNS, SDK_DEFAULTS } from './config';\n\n/**\n * Sanitize data by redacting sensitive fields\n * \n * - Recursively traverses objects and arrays\n * - Redacts fields matching sensitive patterns\n * - Masks credit card numbers and SSNs\n * - Truncates large payloads\n */\nexport function sanitize(\n data: unknown,\n maxSize: number = SDK_DEFAULTS.MAX_BODY_SIZE,\n customFields: string[] = []\n): unknown {\n if (data === null || data === undefined) {\n return data;\n }\n\n // Combine default and custom sensitive fields\n const sensitiveFields = [\n ...SENSITIVE_PATTERNS.FIELD_NAMES,\n ...customFields.map(f => f.toLowerCase())\n ];\n\n // Deep clone and sanitize\n const sanitized = deepSanitize(data, sensitiveFields);\n\n // Convert to string to check size\n const jsonString = JSON.stringify(sanitized);\n\n // Truncate if too large\n if (jsonString.length > maxSize) {\n return {\n _truncated: true,\n _originalSize: jsonString.length,\n _message: `Payload exceeded ${maxSize} bytes, truncated`,\n _preview: jsonString.substring(0, 500) + '...'\n };\n }\n\n return sanitized;\n}\n\n/**\n * Deep sanitize an object/array recursively\n */\nfunction deepSanitize(data: unknown, sensitiveFields: string[]): unknown {\n // Handle primitives\n if (typeof data !== 'object' || data === null) {\n // Check string values for patterns\n if (typeof data === 'string') {\n return sanitizeString(data);\n }\n return data;\n }\n\n // Handle arrays\n if (Array.isArray(data)) {\n return data.map(item => deepSanitize(item, sensitiveFields));\n }\n\n // Handle objects\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(data)) {\n const lowerKey = key.toLowerCase();\n\n // Check if this field should be redacted\n if (sensitiveFields.some(field => lowerKey.includes(field))) {\n result[key] = SENSITIVE_PATTERNS.REDACTED;\n } else if (typeof value === 'object' && value !== null) {\n // Recursively sanitize nested objects/arrays\n result[key] = deepSanitize(value, sensitiveFields);\n } else if (typeof value === 'string') {\n // Check string values for patterns\n result[key] = sanitizeString(value);\n } else {\n result[key] = value;\n }\n }\n\n return result;\n}\n\n/**\n * Sanitize a string value by replacing sensitive patterns\n */\nfunction sanitizeString(value: string): string {\n let sanitized = value;\n\n // Replace credit card numbers\n sanitized = sanitized.replace(\n SENSITIVE_PATTERNS.VALUE_PATTERNS.CREDIT_CARD,\n SENSITIVE_PATTERNS.MASKED_CARD\n );\n\n // Replace SSN patterns\n sanitized = sanitized.replace(\n SENSITIVE_PATTERNS.VALUE_PATTERNS.SSN,\n SENSITIVE_PATTERNS.REDACTED\n );\n\n return sanitized;\n}\n\n/**\n * Safely stringify an object, handling circular references\n */\nexport function safeStringify(obj: unknown, maxSize?: number): string | undefined {\n if (obj === undefined || obj === null) {\n return undefined;\n }\n\n try {\n const seen = new WeakSet();\n const result = JSON.stringify(obj, (key, value) => {\n // Handle circular references\n if (typeof value === 'object' && value !== null) {\n if (seen.has(value)) {\n return '[Circular]';\n }\n seen.add(value);\n }\n // Handle BigInt\n if (typeof value === 'bigint') {\n return value.toString();\n }\n // Handle functions\n if (typeof value === 'function') {\n return '[Function]';\n }\n return value;\n });\n\n // Truncate if needed\n if (maxSize && result.length > maxSize) {\n return result.substring(0, maxSize) + '...[truncated]';\n }\n\n return result;\n } catch (error) {\n return '[Unable to stringify]';\n }\n}\n\n/**\n * Extract safe headers (remove sensitive ones)\n */\nexport function sanitizeHeaders(\n headers: Record<string, string | string[] | undefined>\n): Record<string, string | string[] | undefined> {\n const sensitiveHeaders = [\n 'authorization',\n 'cookie',\n 'set-cookie',\n 'x-api-key',\n 'x-auth-token',\n 'x-access-token',\n 'proxy-authorization'\n ];\n\n const result: Record<string, string | string[] | undefined> = {};\n\n for (const [key, value] of Object.entries(headers)) {\n if (sensitiveHeaders.includes(key.toLowerCase())) {\n result[key] = SENSITIVE_PATTERNS.REDACTED;\n } else {\n result[key] = value;\n }\n }\n\n return result;\n}\n","import type { Request, Response, NextFunction } from 'express';\nimport { v4 as uuidv4 } from 'uuid';\nimport { GateOpsOptions, GateOpsRequest, TrafficLog } from './types';\nimport { SDK_DEFAULTS } from './config';\nimport { buffer } from './buffer';\nimport { sanitize, safeStringify, sanitizeHeaders } from './sanitizer';\nimport { initializeSchema } from './db';\n\n/**\n * GateOps Express Middleware\n * \n * Captures request/response cycles for API observability.\n * \n * Features:\n * - Generates unique trace ID for each request\n * - Captures request body, headers, query params\n * - Intercepts response body\n * - Measures request duration\n * - Sanitizes sensitive data\n * - Buffers logs for batch processing\n */\nexport function createMiddleware(options: GateOpsOptions = {}) {\n // Check if SDK is enabled\n const isEnabled = options.enabled ??\n (process.env.GATEOPS_ENABLED !== 'false');\n\n // Return no-op middleware if disabled\n if (!isEnabled) {\n return (_req: Request, _res: Response, next: NextFunction) => {\n next();\n };\n }\n\n // Initialize database\n initializeSchema();\n\n // Initialize buffer\n buffer.initialize({\n maxSize: options.bufferSize || SDK_DEFAULTS.BUFFER_MAX_SIZE,\n intervalMs: options.flushInterval || SDK_DEFAULTS.BUFFER_FLUSH_INTERVAL,\n localOnly: options.localOnly,\n username: process.env.GATEOPS_USERNAME,\n apiKey: process.env.GATEOPS_API_KEY\n });\n\n // Excluded paths\n const excludePaths = new Set([\n ...(options.excludePaths || []),\n SDK_DEFAULTS.ROUTE_PREFIX, // Don't log our own routes\n '/.well-known/gateops'\n ]);\n\n // Max body size\n const maxBodySize = options.maxBodySize || SDK_DEFAULTS.MAX_BODY_SIZE;\n\n // Custom sensitive fields\n const sensitiveFields = options.sensitiveFields || [];\n\n return function gateopsMiddleware(\n req: Request,\n res: Response,\n next: NextFunction\n ) {\n // Skip excluded paths\n if (shouldExclude(req.path, excludePaths)) {\n return next();\n }\n\n // Generate trace ID\n const traceId = uuidv4();\n const startTime = Date.now();\n\n // Attach GateOps context to request\n (req as GateOpsRequest).gateops = {\n traceId,\n startTime\n };\n\n // Capture response body\n const chunks: Buffer[] = [];\n const originalWrite = res.write.bind(res);\n const originalEnd = res.end.bind(res);\n\n // Override res.write\n res.write = function (\n chunk: any,\n encodingOrCallback?: BufferEncoding | ((error: Error | null | undefined) => void),\n callback?: (error: Error | null | undefined) => void\n ): boolean {\n if (chunk) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n\n // Handle overloaded signatures\n if (typeof encodingOrCallback === 'function') {\n return originalWrite(chunk, encodingOrCallback);\n }\n return originalWrite(chunk, encodingOrCallback, callback);\n };\n\n // Override res.end\n res.end = function (\n chunk?: any,\n encodingOrCallback?: BufferEncoding | (() => void),\n callback?: () => void\n ): Response {\n // Capture final chunk\n if (chunk) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n\n // Calculate duration\n const duration = Date.now() - startTime;\n\n // Get response body\n const responseBody = Buffer.concat(chunks).toString('utf-8');\n\n // Create log entry\n const log = createLogEntry(\n req,\n res,\n traceId,\n duration,\n responseBody,\n maxBodySize,\n sensitiveFields\n );\n\n // Push to buffer\n buffer.push(log);\n\n // Call original end\n if (typeof encodingOrCallback === 'function') {\n return originalEnd(chunk, encodingOrCallback);\n }\n return originalEnd(chunk, encodingOrCallback, callback);\n };\n\n next();\n };\n}\n\n/**\n * Check if a path should be excluded from logging\n */\nfunction shouldExclude(path: string, excludePaths: Set<string>): boolean {\n // Direct match\n if (excludePaths.has(path)) {\n return true;\n }\n\n // Prefix match for GateOps routes\n for (const excluded of excludePaths) {\n if (path.startsWith(excluded)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Create a sanitized log entry from request/response\n */\nfunction createLogEntry(\n req: Request,\n res: Response,\n traceId: string,\n duration: number,\n responseBody: string,\n maxBodySize: number,\n sensitiveFields: string[]\n): TrafficLog {\n // Parse and sanitize request body\n let reqBody: unknown = req.body;\n if (typeof reqBody === 'object') {\n reqBody = sanitize(reqBody, maxBodySize, sensitiveFields);\n }\n\n // Parse and sanitize response body\n let resBody: unknown;\n try {\n resBody = JSON.parse(responseBody);\n resBody = sanitize(resBody, maxBodySize, sensitiveFields);\n } catch {\n // Not JSON, truncate if too long\n resBody = responseBody.length > maxBodySize\n ? responseBody.substring(0, maxBodySize) + '...[truncated]'\n : responseBody;\n }\n\n // Get client IP\n const ip = req.ip ||\n req.headers['x-forwarded-for']?.toString().split(',')[0] ||\n req.socket?.remoteAddress ||\n 'unknown';\n\n return {\n trace_id: traceId,\n endpoint: req.path,\n method: req.method,\n status: res.statusCode,\n duration_ms: duration,\n req_headers: safeStringify(sanitizeHeaders(req.headers as Record<string, string>)),\n res_headers: safeStringify(sanitizeHeaders(res.getHeaders() as Record<string, string>)),\n req_body: safeStringify(reqBody, maxBodySize),\n res_body: safeStringify(resBody, maxBodySize),\n query_params: safeStringify(req.query),\n ip_address: ip,\n user_agent: req.headers['user-agent'],\n created_at: new Date()\n };\n}\n\nexport default createMiddleware;\n","import { Router, Request, Response } from 'express';\nimport { SDK_DEFAULTS } from './config';\nimport { getDatabase, trafficLogs, endpoints, config } from './db';\nimport { desc, eq, and, gte, lte, like } from 'drizzle-orm';\n\n/**\n * GateOps Exposed Routes\n * \n * Routes exposed on the user's Express app for Panel to query.\n * All routes are prefixed with /.well-known/gateops/\n * \n * Authentication: x-gateops-username + x-gateops-api-key headers\n */\n\nconst router = Router();\n\n/**\n * Authentication middleware for exposed routes\n */\nfunction authenticate(req: Request, res: Response, next: Function): void {\n const username = req.headers['x-gateops-username'] as string;\n const apiKey = req.headers['x-gateops-api-key'] as string;\n\n const expectedUsername = process.env.GATEOPS_USERNAME;\n const expectedApiKey = process.env.GATEOPS_API_KEY;\n\n if (!expectedUsername || !expectedApiKey) {\n res.status(503).json({\n error: 'GateOps not configured',\n message: 'GATEOPS_USERNAME and GATEOPS_API_KEY must be set'\n });\n return;\n }\n\n if (username !== expectedUsername || apiKey !== expectedApiKey) {\n res.status(401).json({\n error: 'Unauthorized',\n message: 'Invalid credentials'\n });\n return;\n }\n\n next();\n}\n\n// Apply auth to all routes\nrouter.use(authenticate);\n\n/**\n * GET /.well-known/gateops/health\n * \n * Health check endpoint, returns SDK version and status\n */\nrouter.get('/health', (_req: Request, res: Response) => {\n res.json({\n status: 'ok',\n version: require('../package.json').version,\n timestamp: new Date().toISOString()\n });\n});\n\n/**\n * GET /.well-known/gateops/logs\n * \n * Fetch traffic logs with pagination and filters\n * \n * Query params:\n * - page: Page number (default: 1)\n * - limit: Items per page (default: 50, max: 100)\n * - status: Filter by status code\n * - method: Filter by HTTP method\n * - endpoint: Filter by endpoint (partial match)\n * - from: Filter from date (ISO string)\n * - to: Filter to date (ISO string)\n * - minDuration: Filter by minimum duration (ms)\n */\nrouter.get('/logs', async (req: Request, res: Response) => {\n try {\n const db = getDatabase();\n\n // Pagination\n const page = Math.max(1, parseInt(req.query.page as string) || 1);\n const limit = Math.min(100, Math.max(1, parseInt(req.query.limit as string) || 50));\n const offset = (page - 1) * limit;\n\n // Build base query\n let query = db.select().from(trafficLogs);\n\n // Apply filters\n const conditions = [];\n\n if (req.query.status) {\n conditions.push(eq(trafficLogs.status, parseInt(req.query.status as string)));\n }\n\n if (req.query.method) {\n conditions.push(eq(trafficLogs.method, (req.query.method as string).toUpperCase()));\n }\n\n if (req.query.endpoint) {\n conditions.push(like(trafficLogs.endpoint, `%${req.query.endpoint}%`));\n }\n\n if (req.query.from) {\n conditions.push(gte(trafficLogs.created_at, new Date(req.query.from as string)));\n }\n\n if (req.query.to) {\n conditions.push(lte(trafficLogs.created_at, new Date(req.query.to as string)));\n }\n\n if (req.query.minDuration) {\n conditions.push(gte(trafficLogs.duration_ms, parseInt(req.query.minDuration as string)));\n }\n\n // Execute query\n const results = await query\n .where(conditions.length > 0 ? and(...conditions) : undefined)\n .orderBy(desc(trafficLogs.created_at))\n .limit(limit)\n .offset(offset);\n\n // Get total count for pagination\n const countResult = await db\n .select({ count: trafficLogs.id })\n .from(trafficLogs)\n .where(conditions.length > 0 ? and(...conditions) : undefined);\n\n const total = countResult.length;\n\n res.json({\n logs: results,\n pagination: {\n page,\n limit,\n total,\n totalPages: Math.ceil(total / limit)\n }\n });\n } catch (error) {\n console.error('[GateOps] Error fetching logs:', error);\n res.status(500).json({ error: 'Failed to fetch logs' });\n }\n});\n\n/**\n * GET /.well-known/gateops/logs/:traceId\n * \n * Get a single log entry by trace ID\n */\nrouter.get('/logs/:traceId', async (req: Request, res: Response) => {\n try {\n const db = getDatabase();\n\n const result = await db\n .select()\n .from(trafficLogs)\n .where(eq(trafficLogs.trace_id, req.params.traceId))\n .limit(1);\n\n if (result.length === 0) {\n res.status(404).json({ error: 'Log not found' });\n return;\n }\n\n res.json(result[0]);\n } catch (error) {\n console.error('[GateOps] Error fetching log:', error);\n res.status(500).json({ error: 'Failed to fetch log' });\n }\n});\n\n/**\n * GET /.well-known/gateops/endpoints\n * \n * Get all discovered endpoints\n */\nrouter.get('/endpoints', async (_req: Request, res: Response) => {\n try {\n const db = getDatabase();\n\n const results = await db\n .select()\n .from(endpoints)\n .orderBy(endpoints.path);\n\n res.json({\n endpoints: results,\n total: results.length\n });\n } catch (error) {\n console.error('[GateOps] Error fetching endpoints:', error);\n res.status(500).json({ error: 'Failed to fetch endpoints' });\n }\n});\n\n/**\n * GET /.well-known/gateops/config\n * \n * Get SDK configuration\n */\nrouter.get('/config', async (_req: Request, res: Response) => {\n try {\n const db = getDatabase();\n\n const results = await db.select().from(config);\n\n // Convert to key-value object\n const configObj: Record<string, unknown> = {};\n for (const row of results) {\n try {\n configObj[row.key] = JSON.parse(row.value);\n } catch {\n configObj[row.key] = row.value;\n }\n }\n\n res.json({\n config: configObj,\n defaults: {\n bufferSize: SDK_DEFAULTS.BUFFER_MAX_SIZE,\n flushInterval: SDK_DEFAULTS.BUFFER_FLUSH_INTERVAL,\n maxBodySize: SDK_DEFAULTS.MAX_BODY_SIZE,\n logTtlDays: SDK_DEFAULTS.LOG_TTL_DAYS\n }\n });\n } catch (error) {\n console.error('[GateOps] Error fetching config:', error);\n res.status(500).json({ error: 'Failed to fetch config' });\n }\n});\n\n/**\n * GET /.well-known/gateops/stats\n * \n * Get basic statistics\n */\nrouter.get('/stats', async (_req: Request, res: Response) => {\n try {\n const db = getDatabase();\n\n // Get total logs\n const logsCount = await db.select().from(trafficLogs);\n\n // Get endpoints count\n const endpointsCount = await db.select().from(endpoints);\n\n // Get error rate (5xx responses)\n const errors = logsCount.filter(l => l.status >= 500);\n\n // Get average duration\n const avgDuration = logsCount.length > 0\n ? logsCount.reduce((sum, l) => sum + l.duration_ms, 0) / logsCount.length\n : 0;\n\n res.json({\n totalLogs: logsCount.length,\n totalEndpoints: endpointsCount.length,\n errorCount: errors.length,\n errorRate: logsCount.length > 0\n ? ((errors.length / logsCount.length) * 100).toFixed(2) + '%'\n : '0%',\n avgDurationMs: Math.round(avgDuration)\n });\n } catch (error) {\n console.error('[GateOps] Error fetching stats:', error);\n res.status(500).json({ error: 'Failed to fetch stats' });\n }\n});\n\nexport default router;\nexport { router as gateopsRouter };\n","import { Express, Router } from 'express';\nimport { getDatabase, endpoints } from './db';\nimport { EndpointInfo, RouteLayer, ExpressApp } from './types';\nimport { eq, and } from 'drizzle-orm';\n\n/**\n * Route Scanner - Discovery Engine\n * \n * Scans Express app router stack to extract all registered routes.\n * Runs on app startup to populate the endpoints table.\n */\n\n/**\n * Scan all routes from an Express app\n */\nexport function scanRoutes(app: Express | ExpressApp): EndpointInfo[] {\n const routes: EndpointInfo[] = [];\n\n const expressApp = app as ExpressApp;\n\n if (!expressApp._router) {\n console.warn('[GateOps] No router found on app. Routes will be discovered on first request.');\n return routes;\n }\n\n // Traverse the router stack\n traverseStack(expressApp._router.stack, '', routes);\n\n return routes;\n}\n\n/**\n * Recursively traverse router stack to extract routes\n */\nfunction traverseStack(\n stack: RouteLayer[],\n basePath: string,\n routes: EndpointInfo[]\n): void {\n for (const layer of stack) {\n if (layer.route) {\n // This is a route layer\n const routePath = joinPaths(basePath, layer.route.path);\n const methods = Object.keys(layer.route.methods)\n .filter(m => layer.route!.methods[m])\n .map(m => m.toUpperCase());\n\n // Get middleware names from route stack\n const middlewareNames = layer.route.stack\n .map(l => l.name)\n .filter(n => n && n !== '<anonymous>');\n\n for (const method of methods) {\n routes.push({\n path: normalizePath(routePath),\n method,\n middleware_names: JSON.stringify(middlewareNames),\n last_seen: new Date()\n });\n }\n } else if (layer.name === 'router' && layer.handle) {\n // This is a nested router\n const routerPath = getLayerPath(layer);\n const nestedRouter = layer.handle as Router & { stack?: RouteLayer[] };\n\n if (nestedRouter.stack) {\n traverseStack(\n nestedRouter.stack,\n joinPaths(basePath, routerPath),\n routes\n );\n }\n }\n }\n}\n\n/**\n * Get the path from a router layer\n */\nfunction getLayerPath(layer: RouteLayer): string {\n if (layer.path) {\n return layer.path;\n }\n\n // Extract path from regexp\n if (layer.regexp) {\n const match = layer.regexp.toString().match(/^\\/\\^(.*?)\\\\\\//);\n if (match) {\n return match[1].replace(/\\\\\\//g, '/');\n }\n }\n\n return '';\n}\n\n/**\n * Join path segments\n */\nfunction joinPaths(base: string, path: string): string {\n if (!base) return path;\n if (!path) return base;\n\n const normalizedBase = base.endsWith('/') ? base.slice(0, -1) : base;\n const normalizedPath = path.startsWith('/') ? path : `/${path}`;\n\n return normalizedBase + normalizedPath;\n}\n\n/**\n * Normalize a path (handle params, etc.)\n */\nfunction normalizePath(path: string): string {\n // Replace Express param patterns like :id with {id}\n return path.replace(/:(\\w+)/g, '{$1}');\n}\n\n/**\n * Sync discovered routes to database\n */\nexport async function syncRoutesToDatabase(routes: EndpointInfo[]): Promise<void> {\n const db = getDatabase();\n const now = new Date();\n\n for (const route of routes) {\n try {\n // Try to update existing\n const existing = await db\n .select()\n .from(endpoints)\n .where(and(\n eq(endpoints.path, route.path),\n eq(endpoints.method, route.method)\n ))\n .limit(1);\n\n if (existing.length > 0) {\n // Update last_seen\n await db\n .update(endpoints)\n .set({\n last_seen: now,\n middleware_names: route.middleware_names\n })\n .where(and(\n eq(endpoints.path, route.path),\n eq(endpoints.method, route.method)\n ));\n } else {\n // Insert new\n await db.insert(endpoints).values({\n path: route.path,\n method: route.method,\n middleware_names: route.middleware_names,\n last_seen: now\n });\n }\n } catch (error) {\n console.error(`[GateOps] Failed to sync route ${route.method} ${route.path}:`, error);\n }\n }\n}\n\n/**\n * Update endpoint schema based on observed request/response\n */\nexport async function updateEndpointSchema(\n path: string,\n method: string,\n reqSchema: unknown,\n resSchema: unknown\n): Promise<void> {\n const db = getDatabase();\n\n try {\n const existing = await db\n .select()\n .from(endpoints)\n .where(and(\n eq(endpoints.path, path),\n eq(endpoints.method, method)\n ))\n .limit(1);\n\n const schema = {\n request: reqSchema,\n response: resSchema,\n inferredAt: new Date().toISOString()\n };\n\n if (existing.length > 0) {\n await db\n .update(endpoints)\n .set({\n detected_schema: JSON.stringify(schema),\n last_seen: new Date()\n })\n .where(and(\n eq(endpoints.path, path),\n eq(endpoints.method, method)\n ));\n } else {\n await db.insert(endpoints).values({\n path,\n method,\n detected_schema: JSON.stringify(schema),\n last_seen: new Date()\n });\n }\n } catch (error) {\n console.error(`[GateOps] Failed to update schema for ${method} ${path}:`, error);\n }\n}\n\n/**\n * Get all endpoints from database\n */\nexport async function getEndpoints(): Promise<EndpointInfo[]> {\n const db = getDatabase();\n const rows = await db.select().from(endpoints);\n\n return rows.map(row => ({\n id: row.id,\n path: row.path,\n method: row.method,\n detected_schema: row.detected_schema || undefined,\n middleware_names: row.middleware_names || undefined,\n last_seen: row.last_seen\n }));\n}\n","import axios from 'axios';\nimport { getPanelUrl, SDK_DEFAULTS } from './config';\nimport { TrafficLog, EndpointInfo, VerifyResponse, LogSubmitResponse } from './types';\n\n/**\n * Panel Sync Module\n * \n * Handles communication with the GateOps Panel API.\n */\n\n/**\n * Verify credentials with the Panel\n */\nexport async function verifyCredentials(\n username: string,\n apiKey: string\n): Promise<VerifyResponse> {\n try {\n const response = await axios.post<VerifyResponse>(\n getPanelUrl('VERIFY'),\n { username },\n {\n headers: {\n 'Content-Type': 'application/json',\n 'x-gateops-username': username,\n 'x-gateops-api-key': apiKey\n },\n timeout: 10000\n }\n );\n\n return response.data;\n } catch (error) {\n if (axios.isAxiosError(error)) {\n if (error.response?.status === 401) {\n return {\n success: false,\n message: 'Invalid credentials'\n };\n }\n return {\n success: false,\n message: error.message\n };\n }\n return {\n success: false,\n message: 'Connection failed'\n };\n }\n}\n\n/**\n * Send logs to the Panel\n */\nexport async function sendLogs(\n logs: TrafficLog[],\n username: string,\n apiKey: string,\n retryCount: number = 0\n): Promise<LogSubmitResponse> {\n try {\n const response = await axios.post<LogSubmitResponse>(\n getPanelUrl('LOGS'),\n {\n logs: logs.map(log => ({\n ...log,\n created_at: log.created_at instanceof Date\n ? log.created_at.toISOString()\n : log.created_at\n }))\n },\n {\n headers: {\n 'Content-Type': 'application/json',\n 'x-gateops-username': username,\n 'x-gateops-api-key': apiKey\n },\n timeout: 15000\n }\n );\n\n return response.data;\n } catch (error) {\n // Retry with exponential backoff\n if (retryCount < SDK_DEFAULTS.MAX_RETRY_ATTEMPTS) {\n const delay = SDK_DEFAULTS.RETRY_DELAY_BASE * Math.pow(2, retryCount);\n await sleep(delay);\n return sendLogs(logs, username, apiKey, retryCount + 1);\n }\n\n if (axios.isAxiosError(error)) {\n return {\n success: false,\n received: 0,\n message: error.message\n };\n }\n\n return {\n success: false,\n received: 0,\n message: 'Failed to send logs'\n };\n }\n}\n\n/**\n * Send discovered endpoints to the Panel\n */\nexport async function sendEndpoints(\n routes: EndpointInfo[],\n username: string,\n apiKey: string\n): Promise<boolean> {\n try {\n await axios.post(\n getPanelUrl('ENDPOINTS'),\n {\n endpoints: routes.map(r => ({\n path: r.path,\n method: r.method,\n detected_schema: r.detected_schema,\n middleware_names: r.middleware_names,\n last_seen: r.last_seen instanceof Date\n ? r.last_seen.toISOString()\n : r.last_seen\n }))\n },\n {\n headers: {\n 'Content-Type': 'application/json',\n 'x-gateops-username': username,\n 'x-gateops-api-key': apiKey\n },\n timeout: 10000\n }\n );\n\n return true;\n } catch (error) {\n console.warn('[GateOps] Failed to send endpoints to Panel:',\n axios.isAxiosError(error) ? error.message : error\n );\n return false;\n }\n}\n\n/**\n * Send heartbeat to Panel\n */\nexport async function sendHeartbeat(\n username: string,\n apiKey: string\n): Promise<boolean> {\n try {\n await axios.post(\n getPanelUrl('HEARTBEAT'),\n {\n timestamp: new Date().toISOString(),\n sdkVersion: require('../package.json').version\n },\n {\n headers: {\n 'Content-Type': 'application/json',\n 'x-gateops-username': username,\n 'x-gateops-api-key': apiKey\n },\n timeout: 5000\n }\n );\n\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Sleep helper\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n","/**\n * GateOps SDK - Lightweight API Observability for Express.js\n * \n * @packageDocumentation\n * \n * @example\n * ```typescript\n * import gateops from 'gateops-core';\n * \n * const app = express();\n * \n * // Initialize GateOps middleware\n * app.use(gateops.init());\n * \n * // Your routes...\n * app.get('/api/users', (req, res) => { ... });\n * \n * app.listen(3000);\n * ```\n */\n\nimport { Express } from 'express';\nimport createMiddleware from './middleware';\nimport { gateopsRouter } from './routes';\nimport { scanRoutes, syncRoutesToDatabase } from './scanner';\nimport { SDK_DEFAULTS } from './config';\nimport { GateOpsOptions, ExpressApp } from './types';\nimport { buffer } from './buffer';\nimport { sendEndpoints } from './sync';\n\n// Track if routes have been scanned\nlet routesScanned = false;\n\n/**\n * Initialize GateOps SDK\n * \n * Returns an Express middleware that captures all API traffic.\n * \n * @param options - Configuration options\n * @returns Express middleware function\n * \n * @example\n * ```typescript\n * // Basic usage\n * app.use(gateops.init());\n * \n * // With options\n * app.use(gateops.init({\n * excludePaths: ['/health', '/metrics'],\n * sensitiveFields: ['customSecret'],\n * localOnly: true // Don't send to Panel\n * }));\n * ```\n */\nfunction init(options: GateOpsOptions = {}) {\n const middleware = createMiddleware(options);\n\n // Return wrapped middleware that also mounts routes\n return function gateopsInit(req: any, res: any, next: any) {\n // Mount exposed routes on first request (if enabled)\n if (options.exposeRoutes !== false && req.app && !req.app._gateopsRoutesRegistered) {\n req.app.use(SDK_DEFAULTS.ROUTE_PREFIX, gateopsRouter);\n req.app._gateopsRoutesRegistered = true;\n }\n\n return middleware(req, res, next);\n };\n}\n\n/**\n * Scan and register all routes from an Express app\n * \n * Call this after all routes are registered, typically\n * right before `app.listen()`.\n * \n * @param app - Express application instance\n * \n * @example\n * ```typescript\n * // Register routes first\n * app.use('/api', apiRouter);\n * \n * // Then scan\n * gateops.scan(app);\n * \n * app.listen(3000);\n * ```\n */\nasync function scan(app: Express): Promise<void> {\n if (routesScanned) {\n return;\n }\n\n const routes = scanRoutes(app as unknown as ExpressApp);\n\n if (routes.length === 0) {\n console.warn('[GateOps] No routes found. Make sure to call scan() after registering routes.');\n return;\n }\n\n console.log(`[GateOps] Discovered ${routes.length} routes`);\n\n // Sync to local database\n await syncRoutesToDatabase(routes);\n\n // Send to Panel (if credentials are set)\n const username = process.env.GATEOPS_USERNAME;\n const apiKey = process.env.GATEOPS_API_KEY;\n\n if (username && apiKey) {\n await sendEndpoints(routes, username, apiKey);\n }\n\n routesScanned = true;\n}\n\n/**\n * Manually flush the log buffer\n * \n * Useful for testing or before graceful shutdown.\n */\nasync function flush(): Promise<void> {\n await buffer.flush();\n}\n\n/**\n * Shutdown GateOps SDK\n * \n * Call this before application exit for graceful shutdown.\n */\nfunction shutdown(): void {\n buffer.shutdown();\n}\n\n// Main export object\nconst gateops = {\n init,\n scan,\n flush,\n shutdown\n};\n\n// Exports\nexport default gateops;\nexport { init, scan, flush, shutdown };\n\n// Export types\nexport type { GateOpsOptions, TrafficLog, EndpointInfo } from './types';\n\n// Export utilities for advanced usage\nexport { sanitize, safeStringify, sanitizeHeaders } from './sanitizer';\nexport { getDatabase, initializeSchema, closeDatabase, cleanupOldLogs } from './db';\nexport { scanRoutes, syncRoutesToDatabase, getEndpoints } from './scanner';\nexport { verifyCredentials, sendLogs, sendEndpoints } from './sync';\nexport { buffer } from './buffer';\nexport { gateopsRouter } from './routes';\nexport { SDK_DEFAULTS, PANEL_ENDPOINTS, getPanelUrl } from './config';\n"]}
1
+ {"version":3,"sources":["../package.json","../src/config.ts","../src/db/schema.ts","../src/db/index.ts","../src/buffer/disk.ts","../src/buffer/index.ts","../src/sanitizer.ts","../src/middleware.ts","../src/routes.ts","../src/scanner.ts","../src/sync.ts","../src/index.ts"],"names":["exports","fs","path2","db","axios","uuidv4","path","and","eq"],"mappings":"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","file":"index.mjs","sourcesContent":["{\n \"name\": \"gateops-core\",\n \"version\": \"0.2.0\",\n \"description\": \"Lightweight API observability SDK for Express.js - Zero-config, privacy-first traffic monitoring\",\n \"main\": \"dist/index.js\",\n \"module\": \"dist/index.mjs\",\n \"types\": \"dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"require\": \"./dist/index.js\",\n \"import\": \"./dist/index.mjs\",\n \"types\": \"./dist/index.d.ts\"\n },\n \"./register\": {\n \"require\": \"./dist/register.js\"\n }\n },\n \"bin\": {\n \"gateops-init\": \"dist/bin/gateops-init.js\"\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"test\": \"vitest\",\n \"test:run\": \"vitest run\",\n \"lint\": \"eslint src --ext .ts\",\n \"format\": \"prettier --write src\",\n \"prepublishOnly\": \"npm run build\"\n },\n \"keywords\": [\n \"api\",\n \"observability\",\n \"monitoring\",\n \"express\",\n \"middleware\",\n \"logging\",\n \"debugging\",\n \"documentation\",\n \"swagger\",\n \"openapi\"\n ],\n \"author\": \"GateOps\",\n \"license\": \"MIT\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/gateops/gateops-core\"\n },\n \"engines\": {\n \"node\": \">=18.0.0\"\n },\n \"peerDependencies\": {\n \"express\": \"^4.18.0 || ^5.0.0\"\n },\n \"dependencies\": {\n \"axios\": \"^1.6.0\",\n \"better-sqlite3\": \"^11.0.0\",\n \"chalk\": \"^4.1.2\",\n \"commander\": \"^12.0.0\",\n \"drizzle-orm\": \"^0.29.0\",\n \"inquirer\": \"^8.2.6\",\n \"uuid\": \"^9.0.0\",\n \"zod\": \"^3.22.0\"\n },\n \"devDependencies\": {\n \"@types/better-sqlite3\": \"^7.6.8\",\n \"@types/express\": \"^4.17.21\",\n \"@types/inquirer\": \"^8.2.10\",\n \"@types/node\": \"^20.10.0\",\n \"@types/uuid\": \"^9.0.7\",\n \"drizzle-kit\": \"^0.20.0\",\n \"eslint\": \"^8.56.0\",\n \"express\": \"^4.18.2\",\n \"prettier\": \"^3.2.0\",\n \"tsup\": \"^8.0.0\",\n \"typescript\": \"^5.3.0\",\n \"vitest\": \"^1.2.0\"\n }\n}","/**\n * GateOps SDK Configuration\n * \n * Panel API endpoints are centralized here for easy modification.\n * Change these values if the Panel API structure changes.\n */\n\n// Panel base URL - change this if hosting changes\nexport const PANEL_BASE_URL = process.env.GATEOPS_PANEL_URL || 'https://gateops.sleeksoulsmedia.com';\n\n/**\n * Panel API Endpoints\n * \n * Modify these paths if the Panel API structure changes.\n * All paths are relative to PANEL_BASE_URL.\n */\nexport const PANEL_ENDPOINTS = {\n // Verify API key during initialization\n VERIFY: '/api/sdk/verify',\n\n // Send batched logs to Panel\n LOGS: '/api/sdk/logs',\n\n // Fetch remote configuration (optional)\n CONFIG: '/api/sdk/config',\n\n // Send discovered endpoints/routes\n ENDPOINTS: '/api/sdk/endpoints',\n\n // Heartbeat/health check\n HEARTBEAT: '/api/sdk/heartbeat'\n} as const;\n\n/**\n * SDK Default Configuration\n */\nexport const SDK_DEFAULTS = {\n // Buffer settings\n BUFFER_MAX_SIZE: 50, // Flush when buffer reaches this size\n BUFFER_FLUSH_INTERVAL: 10000, // Flush every 10 seconds (ms)\n\n // Payload limits\n MAX_BODY_SIZE: 10240, // 10KB max for req/res bodies\n\n // Log retention\n LOG_TTL_DAYS: 15, // Auto-cleanup logs older than 15 days\n\n // Retry settings\n MAX_RETRY_ATTEMPTS: 3,\n RETRY_DELAY_BASE: 1000, // Base delay for exponential backoff (ms)\n\n // Database\n DEFAULT_DB_PATH: '.gateops/data.sqlite',\n BUFFER_FILE_PATH: '.gateops/buffer.json',\n\n // Route prefix for exposed endpoints\n ROUTE_PREFIX: '/.well-known/gateops'\n} as const;\n\n/**\n * Sensitive field patterns for sanitization\n */\nexport const SENSITIVE_PATTERNS = {\n // Field names to redact (case-insensitive)\n FIELD_NAMES: [\n 'password',\n 'passwd',\n 'secret',\n 'token',\n 'apikey',\n 'api_key',\n 'api-key',\n 'authorization',\n 'auth',\n 'bearer',\n 'credential',\n 'private',\n 'ssn',\n 'credit_card',\n 'creditcard',\n 'card_number',\n 'cvv',\n 'pin'\n ],\n\n // Regex patterns for value-based detection\n VALUE_PATTERNS: {\n // Credit card (basic pattern)\n CREDIT_CARD: /\\b\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}\\b/g,\n // SSN pattern\n SSN: /\\b\\d{3}[-]?\\d{2}[-]?\\d{4}\\b/g\n },\n\n // Replacement text\n REDACTED: '[REDACTED]',\n MASKED_CARD: '****-****-****-****'\n} as const;\n\n/**\n * Get full Panel endpoint URL\n */\nexport function getPanelUrl(endpoint: keyof typeof PANEL_ENDPOINTS): string {\n return `${PANEL_BASE_URL}${PANEL_ENDPOINTS[endpoint]}`;\n}\n\nexport type PanelEndpointKey = keyof typeof PANEL_ENDPOINTS;\n","import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';\n\n/**\n * Traffic logs table - stores all captured API requests/responses\n * \n * TTL: 15 days (cleanup handled by SDK)\n */\nexport const trafficLogs = sqliteTable('gateops_traffic_logs', {\n id: integer('id').primaryKey({ autoIncrement: true }),\n\n // Unique identifier for request tracing\n trace_id: text('trace_id').notNull(),\n\n // Request info\n endpoint: text('endpoint').notNull(),\n method: text('method').notNull(),\n status: integer('status').notNull(),\n duration_ms: integer('duration_ms').notNull(),\n\n // Headers (JSON strings)\n req_headers: text('req_headers'),\n res_headers: text('res_headers'),\n\n // Bodies (JSON strings, sanitized, max 10KB each)\n req_body: text('req_body'),\n res_body: text('res_body'),\n\n // Additional context\n query_params: text('query_params'),\n ip_address: text('ip_address'),\n user_agent: text('user_agent'),\n\n // Timestamp (stored as Unix timestamp)\n created_at: integer('created_at', { mode: 'timestamp' }).notNull()\n});\n\n/**\n * Endpoints table - stores discovered routes for documentation\n * \n * Updated on each app startup + when new routes are hit\n */\nexport const endpoints = sqliteTable('gateops_endpoints', {\n id: integer('id').primaryKey({ autoIncrement: true }),\n\n // Route identification (unique constraint on path + method)\n path: text('path').notNull(),\n method: text('method').notNull(),\n\n // Inferred request/response schema (JSON string)\n // Deep inference captures nested structures\n detected_schema: text('detected_schema'),\n\n // List of middleware names (JSON array)\n middleware_names: text('middleware_names'),\n\n // Last time this endpoint was hit\n last_seen: integer('last_seen', { mode: 'timestamp' }).notNull()\n});\n\n/**\n * Config table - key/value store for SDK configuration\n * \n * Used for storing latency rules, custom settings, etc.\n */\nexport const config = sqliteTable('gateops_config', {\n // Unique key name\n key: text('key').primaryKey(),\n\n // Value as JSON string\n value: text('value').notNull(),\n\n // When this config was last updated\n updated_at: integer('updated_at', { mode: 'timestamp' })\n});\n\n// Export table types for Drizzle\nexport type TrafficLogInsert = typeof trafficLogs.$inferInsert;\nexport type TrafficLogSelect = typeof trafficLogs.$inferSelect;\n\nexport type EndpointInsert = typeof endpoints.$inferInsert;\nexport type EndpointSelect = typeof endpoints.$inferSelect;\n\nexport type ConfigInsert = typeof config.$inferInsert;\nexport type ConfigSelect = typeof config.$inferSelect;\n","import Database from 'better-sqlite3';\nimport { drizzle, BetterSQLite3Database } from 'drizzle-orm/better-sqlite3';\nimport { sql } from 'drizzle-orm';\nimport * as schema from './schema';\nimport { SDK_DEFAULTS } from '../config';\nimport * as fs from 'fs';\nimport * as path from 'path';\n\nlet db: BetterSQLite3Database<typeof schema> | null = null;\nlet sqliteDb: Database.Database | null = null;\n\n/**\n * Get or create the database connection\n */\nexport function getDatabase(dbPath?: string): BetterSQLite3Database<typeof schema> {\n if (db) {\n return db;\n }\n\n const resolvedPath = dbPath || process.env.GATEOPS_DB_PATH || SDK_DEFAULTS.DEFAULT_DB_PATH;\n const absolutePath = path.isAbsolute(resolvedPath)\n ? resolvedPath\n : path.join(process.cwd(), resolvedPath);\n\n // Ensure directory exists\n const dir = path.dirname(absolutePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n // Create SQLite connection\n sqliteDb = new Database(absolutePath);\n\n // Enable WAL mode for better concurrent performance\n sqliteDb.pragma('journal_mode = WAL');\n\n // Create Drizzle instance\n db = drizzle(sqliteDb, { schema });\n\n return db;\n}\n\n/**\n * Initialize database schema (create tables if not exist)\n */\nexport function initializeSchema(database?: BetterSQLite3Database<typeof schema>): void {\n const targetDb = database || getDatabase();\n\n // Create traffic_logs table\n targetDb.run(sql`\n CREATE TABLE IF NOT EXISTS gateops_traffic_logs (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n trace_id TEXT NOT NULL,\n endpoint TEXT NOT NULL,\n method TEXT NOT NULL,\n status INTEGER NOT NULL,\n duration_ms INTEGER NOT NULL,\n req_headers TEXT,\n res_headers TEXT,\n req_body TEXT,\n res_body TEXT,\n query_params TEXT,\n ip_address TEXT,\n user_agent TEXT,\n created_at INTEGER NOT NULL\n )\n `);\n\n // Create indexes for common queries\n targetDb.run(sql`\n CREATE INDEX IF NOT EXISTS idx_traffic_logs_created_at \n ON gateops_traffic_logs(created_at)\n `);\n\n targetDb.run(sql`\n CREATE INDEX IF NOT EXISTS idx_traffic_logs_endpoint \n ON gateops_traffic_logs(endpoint, method)\n `);\n\n targetDb.run(sql`\n CREATE INDEX IF NOT EXISTS idx_traffic_logs_status \n ON gateops_traffic_logs(status)\n `);\n\n // Create endpoints table\n targetDb.run(sql`\n CREATE TABLE IF NOT EXISTS gateops_endpoints (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n path TEXT NOT NULL,\n method TEXT NOT NULL,\n detected_schema TEXT,\n middleware_names TEXT,\n last_seen INTEGER NOT NULL,\n UNIQUE(path, method)\n )\n `);\n\n // Create config table\n targetDb.run(sql`\n CREATE TABLE IF NOT EXISTS gateops_config (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL,\n updated_at INTEGER\n )\n `);\n}\n\n/**\n * Close database connection\n */\nexport function closeDatabase(): void {\n if (sqliteDb) {\n sqliteDb.close();\n sqliteDb = null;\n db = null;\n }\n}\n\n/**\n * Clean up old logs based on TTL\n */\nexport function cleanupOldLogs(ttlDays: number = SDK_DEFAULTS.LOG_TTL_DAYS): number {\n const database = getDatabase();\n const cutoffDate = new Date();\n cutoffDate.setDate(cutoffDate.getDate() - ttlDays);\n\n const result = database.run(sql`\n DELETE FROM gateops_traffic_logs \n WHERE created_at < ${Math.floor(cutoffDate.getTime() / 1000)}\n `);\n\n return result.changes;\n}\n\n// Re-export schema\nexport * from './schema';\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport { SDK_DEFAULTS } from '../config';\nimport { TrafficLog, BufferState } from '../types';\n\nconst BUFFER_VERSION = '1.0.0';\n\n/**\n * Get the buffer file path\n */\nfunction getBufferFilePath(): string {\n return path.join(process.cwd(), SDK_DEFAULTS.BUFFER_FILE_PATH);\n}\n\n/**\n * Save buffer to disk for crash recovery\n */\nexport function saveToDisk(logs: TrafficLog[]): boolean {\n if (logs.length === 0) {\n return true;\n }\n\n try {\n const filePath = getBufferFilePath();\n const dir = path.dirname(filePath);\n\n // Ensure directory exists\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n const state: BufferState = {\n logs,\n savedAt: new Date().toISOString(),\n version: BUFFER_VERSION\n };\n\n fs.writeFileSync(filePath, JSON.stringify(state, null, 2), 'utf-8');\n return true;\n } catch (error) {\n console.error('[GateOps] Failed to save buffer to disk:', error);\n return false;\n }\n}\n\n/**\n * Load buffer from disk (for crash recovery)\n */\nexport function loadFromDisk(): TrafficLog[] {\n try {\n const filePath = getBufferFilePath();\n\n if (!fs.existsSync(filePath)) {\n return [];\n }\n\n const content = fs.readFileSync(filePath, 'utf-8');\n const state: BufferState = JSON.parse(content);\n\n // Validate version compatibility\n if (state.version !== BUFFER_VERSION) {\n console.warn('[GateOps] Buffer file version mismatch, skipping recovery');\n clearDiskBuffer();\n return [];\n }\n\n // Convert date strings back to Date objects\n const logs = state.logs.map(log => ({\n ...log,\n created_at: new Date(log.created_at)\n }));\n\n console.log(`[GateOps] Recovered ${logs.length} logs from disk buffer`);\n return logs;\n } catch (error) {\n console.error('[GateOps] Failed to load buffer from disk:', error);\n return [];\n }\n}\n\n/**\n * Clear the disk buffer file\n */\nexport function clearDiskBuffer(): boolean {\n try {\n const filePath = getBufferFilePath();\n\n if (fs.existsSync(filePath)) {\n fs.unlinkSync(filePath);\n }\n\n return true;\n } catch (error) {\n console.error('[GateOps] Failed to clear disk buffer:', error);\n return false;\n }\n}\n\n/**\n * Check if a disk buffer exists\n */\nexport function hasDiskBuffer(): boolean {\n return fs.existsSync(getBufferFilePath());\n}\n","import { TrafficLog } from '../types';\nimport { SDK_DEFAULTS, getPanelUrl } from '../config';\nimport { getDatabase, trafficLogs } from '../db';\nimport { saveToDisk, loadFromDisk, clearDiskBuffer, hasDiskBuffer } from './disk';\nimport axios from 'axios';\n\n/**\n * Buffer Manager - handles in-memory buffering with disk overflow\n * \n * Features:\n * - In-memory buffer with configurable size\n * - Auto-flush on size threshold or interval\n * - Dual write: local DB + Panel API\n * - Disk persistence for crash recovery\n */\nclass BufferManager {\n private buffer: TrafficLog[] = [];\n private flushInterval: NodeJS.Timeout | null = null;\n private isInitialized = false;\n private isFlushing = false;\n\n private maxSize: number;\n private intervalMs: number;\n private localOnly: boolean;\n private username: string;\n private apiKey: string;\n\n constructor() {\n this.maxSize = SDK_DEFAULTS.BUFFER_MAX_SIZE;\n this.intervalMs = SDK_DEFAULTS.BUFFER_FLUSH_INTERVAL;\n this.localOnly = false;\n this.username = '';\n this.apiKey = '';\n }\n\n /**\n * Initialize the buffer manager\n */\n initialize(options: {\n maxSize?: number;\n intervalMs?: number;\n localOnly?: boolean;\n username?: string;\n apiKey?: string;\n } = {}): void {\n if (this.isInitialized) {\n return;\n }\n\n this.maxSize = options.maxSize || SDK_DEFAULTS.BUFFER_MAX_SIZE;\n this.intervalMs = options.intervalMs || SDK_DEFAULTS.BUFFER_FLUSH_INTERVAL;\n this.localOnly = options.localOnly || false;\n this.username = options.username || process.env.GATEOPS_USERNAME || '';\n this.apiKey = options.apiKey || process.env.GATEOPS_API_KEY || '';\n\n // Recover from disk if needed\n this.recoverFromDisk();\n\n // Start flush interval\n this.startFlushInterval();\n\n // Register shutdown handlers\n this.registerShutdownHandlers();\n\n this.isInitialized = true;\n }\n\n /**\n * Push a log entry to the buffer\n */\n push(log: TrafficLog): void {\n this.buffer.push(log);\n\n // Check if we need to flush\n if (this.buffer.length >= this.maxSize) {\n this.flush();\n }\n }\n\n /**\n * Flush the buffer to database and Panel\n */\n async flush(): Promise<void> {\n if (this.isFlushing || this.buffer.length === 0) {\n return;\n }\n\n this.isFlushing = true;\n\n // Take current buffer and reset\n const logsToFlush = [...this.buffer];\n this.buffer = [];\n\n try {\n // Write to local database\n await this.writeToDatabase(logsToFlush);\n\n // Send to Panel (if not local-only mode)\n if (!this.localOnly && this.username && this.apiKey) {\n await this.sendToPanel(logsToFlush);\n }\n\n // Clear disk buffer on successful flush\n clearDiskBuffer();\n } catch (error) {\n console.error('[GateOps] Flush failed:', error);\n\n // Put logs back in buffer for retry\n this.buffer = [...logsToFlush, ...this.buffer];\n\n // Save to disk in case of crash\n saveToDisk(this.buffer);\n } finally {\n this.isFlushing = false;\n }\n }\n\n /**\n * Write logs to local SQLite database\n */\n private async writeToDatabase(logs: TrafficLog[]): Promise<void> {\n const db = getDatabase();\n\n for (const log of logs) {\n await db.insert(trafficLogs).values({\n trace_id: log.trace_id,\n endpoint: log.endpoint,\n method: log.method,\n status: log.status,\n duration_ms: log.duration_ms,\n req_headers: log.req_headers,\n res_headers: log.res_headers,\n req_body: log.req_body,\n res_body: log.res_body,\n query_params: log.query_params,\n ip_address: log.ip_address,\n user_agent: log.user_agent,\n created_at: log.created_at\n });\n }\n }\n\n /**\n * Send logs to Panel API\n */\n private async sendToPanel(logs: TrafficLog[]): Promise<void> {\n const url = getPanelUrl('LOGS');\n\n try {\n await axios.post(url, {\n logs: logs.map(log => ({\n ...log,\n created_at: log.created_at.toISOString()\n }))\n }, {\n headers: {\n 'Content-Type': 'application/json',\n 'x-gateops-username': this.username,\n 'x-gateops-api-key': this.apiKey\n },\n timeout: 10000 // 10 second timeout\n });\n } catch (error) {\n // Log but don't throw - local DB write is the priority\n console.warn('[GateOps] Failed to send logs to Panel:',\n axios.isAxiosError(error) ? error.message : error\n );\n }\n }\n\n /**\n * Recover logs from disk buffer\n */\n private recoverFromDisk(): void {\n if (hasDiskBuffer()) {\n const recoveredLogs = loadFromDisk();\n if (recoveredLogs.length > 0) {\n this.buffer = [...recoveredLogs, ...this.buffer];\n clearDiskBuffer();\n\n // Trigger flush of recovered logs\n setTimeout(() => this.flush(), 1000);\n }\n }\n }\n\n /**\n * Start the periodic flush interval\n */\n private startFlushInterval(): void {\n if (this.flushInterval) {\n clearInterval(this.flushInterval);\n }\n\n this.flushInterval = setInterval(() => {\n this.flush();\n }, this.intervalMs);\n\n // Don't keep Node.js alive just for this\n this.flushInterval.unref();\n }\n\n /**\n * Register handlers for graceful shutdown\n */\n private registerShutdownHandlers(): void {\n const gracefulShutdown = () => {\n // Save buffer to disk before exit\n if (this.buffer.length > 0) {\n saveToDisk(this.buffer);\n }\n\n // Try to flush synchronously (best effort)\n this.flush();\n\n // Clear interval\n if (this.flushInterval) {\n clearInterval(this.flushInterval);\n }\n };\n\n process.on('SIGINT', gracefulShutdown);\n process.on('SIGTERM', gracefulShutdown);\n process.on('beforeExit', gracefulShutdown);\n\n // Handle uncaught exceptions - save to disk\n process.on('uncaughtException', (error) => {\n console.error('[GateOps] Uncaught exception, saving buffer to disk:', error);\n saveToDisk(this.buffer);\n });\n }\n\n /**\n * Get current buffer size\n */\n getSize(): number {\n return this.buffer.length;\n }\n\n /**\n * Shutdown the buffer manager\n */\n shutdown(): void {\n if (this.flushInterval) {\n clearInterval(this.flushInterval);\n this.flushInterval = null;\n }\n\n // Final flush\n if (this.buffer.length > 0) {\n saveToDisk(this.buffer);\n }\n\n this.isInitialized = false;\n }\n}\n\n// Export singleton instance\nexport const buffer = new BufferManager();\n\n// Re-export disk utilities\nexport { saveToDisk, loadFromDisk, clearDiskBuffer, hasDiskBuffer } from './disk';\n","import { SENSITIVE_PATTERNS, SDK_DEFAULTS } from './config';\n\n/**\n * Sanitize data by redacting sensitive fields\n * \n * - Recursively traverses objects and arrays\n * - Redacts fields matching sensitive patterns\n * - Masks credit card numbers and SSNs\n * - Truncates large payloads\n */\nexport function sanitize(\n data: unknown,\n maxSize: number = SDK_DEFAULTS.MAX_BODY_SIZE,\n customFields: string[] = []\n): unknown {\n if (data === null || data === undefined) {\n return data;\n }\n\n // Combine default and custom sensitive fields\n const sensitiveFields = [\n ...SENSITIVE_PATTERNS.FIELD_NAMES,\n ...customFields.map(f => f.toLowerCase())\n ];\n\n // Deep clone and sanitize\n const sanitized = deepSanitize(data, sensitiveFields);\n\n // Convert to string to check size\n const jsonString = JSON.stringify(sanitized);\n\n // Truncate if too large\n if (jsonString.length > maxSize) {\n return {\n _truncated: true,\n _originalSize: jsonString.length,\n _message: `Payload exceeded ${maxSize} bytes, truncated`,\n _preview: jsonString.substring(0, 500) + '...'\n };\n }\n\n return sanitized;\n}\n\n/**\n * Deep sanitize an object/array recursively\n */\nfunction deepSanitize(data: unknown, sensitiveFields: string[]): unknown {\n // Handle primitives\n if (typeof data !== 'object' || data === null) {\n // Check string values for patterns\n if (typeof data === 'string') {\n return sanitizeString(data);\n }\n return data;\n }\n\n // Handle arrays\n if (Array.isArray(data)) {\n return data.map(item => deepSanitize(item, sensitiveFields));\n }\n\n // Handle objects\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(data)) {\n const lowerKey = key.toLowerCase();\n\n // Check if this field should be redacted\n if (sensitiveFields.some(field => lowerKey.includes(field))) {\n result[key] = SENSITIVE_PATTERNS.REDACTED;\n } else if (typeof value === 'object' && value !== null) {\n // Recursively sanitize nested objects/arrays\n result[key] = deepSanitize(value, sensitiveFields);\n } else if (typeof value === 'string') {\n // Check string values for patterns\n result[key] = sanitizeString(value);\n } else {\n result[key] = value;\n }\n }\n\n return result;\n}\n\n/**\n * Sanitize a string value by replacing sensitive patterns\n */\nfunction sanitizeString(value: string): string {\n let sanitized = value;\n\n // Replace credit card numbers\n sanitized = sanitized.replace(\n SENSITIVE_PATTERNS.VALUE_PATTERNS.CREDIT_CARD,\n SENSITIVE_PATTERNS.MASKED_CARD\n );\n\n // Replace SSN patterns\n sanitized = sanitized.replace(\n SENSITIVE_PATTERNS.VALUE_PATTERNS.SSN,\n SENSITIVE_PATTERNS.REDACTED\n );\n\n return sanitized;\n}\n\n/**\n * Safely stringify an object, handling circular references\n */\nexport function safeStringify(obj: unknown, maxSize?: number): string | undefined {\n if (obj === undefined || obj === null) {\n return undefined;\n }\n\n try {\n const seen = new WeakSet();\n const result = JSON.stringify(obj, (key, value) => {\n // Handle circular references\n if (typeof value === 'object' && value !== null) {\n if (seen.has(value)) {\n return '[Circular]';\n }\n seen.add(value);\n }\n // Handle BigInt\n if (typeof value === 'bigint') {\n return value.toString();\n }\n // Handle functions\n if (typeof value === 'function') {\n return '[Function]';\n }\n return value;\n });\n\n // Truncate if needed\n if (maxSize && result.length > maxSize) {\n return result.substring(0, maxSize) + '...[truncated]';\n }\n\n return result;\n } catch (error) {\n return '[Unable to stringify]';\n }\n}\n\n/**\n * Extract safe headers (remove sensitive ones)\n */\nexport function sanitizeHeaders(\n headers: Record<string, string | string[] | undefined>\n): Record<string, string | string[] | undefined> {\n const sensitiveHeaders = [\n 'authorization',\n 'cookie',\n 'set-cookie',\n 'x-api-key',\n 'x-auth-token',\n 'x-access-token',\n 'proxy-authorization'\n ];\n\n const result: Record<string, string | string[] | undefined> = {};\n\n for (const [key, value] of Object.entries(headers)) {\n if (sensitiveHeaders.includes(key.toLowerCase())) {\n result[key] = SENSITIVE_PATTERNS.REDACTED;\n } else {\n result[key] = value;\n }\n }\n\n return result;\n}\n","import type { Request, Response, NextFunction } from 'express';\nimport { v4 as uuidv4 } from 'uuid';\nimport { GateOpsOptions, GateOpsRequest, TrafficLog } from './types';\nimport { SDK_DEFAULTS } from './config';\nimport { buffer } from './buffer';\nimport { sanitize, safeStringify, sanitizeHeaders } from './sanitizer';\nimport { initializeSchema } from './db';\n\n/**\n * GateOps Express Middleware\n * \n * Captures request/response cycles for API observability.\n * \n * Features:\n * - Generates unique trace ID for each request\n * - Captures request body, headers, query params\n * - Intercepts response body\n * - Measures request duration\n * - Sanitizes sensitive data\n * - Buffers logs for batch processing\n */\nexport function createMiddleware(options: GateOpsOptions = {}) {\n // Check if SDK is enabled\n const isEnabled = options.enabled ??\n (process.env.GATEOPS_ENABLED !== 'false');\n\n // Return no-op middleware if disabled\n if (!isEnabled) {\n return (_req: Request, _res: Response, next: NextFunction) => {\n next();\n };\n }\n\n // Initialize database\n initializeSchema();\n\n // Initialize buffer\n buffer.initialize({\n maxSize: options.bufferSize || SDK_DEFAULTS.BUFFER_MAX_SIZE,\n intervalMs: options.flushInterval || SDK_DEFAULTS.BUFFER_FLUSH_INTERVAL,\n localOnly: options.localOnly,\n username: process.env.GATEOPS_USERNAME,\n apiKey: process.env.GATEOPS_API_KEY\n });\n\n // Excluded paths\n const excludePaths = new Set([\n ...(options.excludePaths || []),\n SDK_DEFAULTS.ROUTE_PREFIX, // Don't log our own routes\n '/.well-known/gateops'\n ]);\n\n // Max body size\n const maxBodySize = options.maxBodySize || SDK_DEFAULTS.MAX_BODY_SIZE;\n\n // Custom sensitive fields\n const sensitiveFields = options.sensitiveFields || [];\n\n return function gateopsMiddleware(\n req: Request,\n res: Response,\n next: NextFunction\n ) {\n // Skip excluded paths\n if (shouldExclude(req.path, excludePaths)) {\n return next();\n }\n\n // Generate trace ID\n const traceId = uuidv4();\n const startTime = Date.now();\n\n // Attach GateOps context to request\n (req as GateOpsRequest).gateops = {\n traceId,\n startTime\n };\n\n // Capture response body\n const chunks: Buffer[] = [];\n const originalWrite = res.write.bind(res);\n const originalEnd = res.end.bind(res);\n\n // Override res.write\n res.write = function (\n chunk: any,\n encodingOrCallback?: BufferEncoding | ((error: Error | null | undefined) => void),\n callback?: (error: Error | null | undefined) => void\n ): boolean {\n if (chunk) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n\n // Handle overloaded signatures\n if (typeof encodingOrCallback === 'function') {\n return originalWrite(chunk, encodingOrCallback);\n }\n return originalWrite(chunk, encodingOrCallback, callback);\n };\n\n // Override res.end\n res.end = function (\n chunk?: any,\n encodingOrCallback?: BufferEncoding | (() => void),\n callback?: () => void\n ): Response {\n // Capture final chunk\n if (chunk) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n\n // Calculate duration\n const duration = Date.now() - startTime;\n\n // Get response body\n const responseBody = Buffer.concat(chunks).toString('utf-8');\n\n // Create log entry\n const log = createLogEntry(\n req,\n res,\n traceId,\n duration,\n responseBody,\n maxBodySize,\n sensitiveFields\n );\n\n // Push to buffer\n buffer.push(log);\n\n // Call original end\n if (typeof encodingOrCallback === 'function') {\n return originalEnd(chunk, encodingOrCallback);\n }\n return originalEnd(chunk, encodingOrCallback, callback);\n };\n\n next();\n };\n}\n\n/**\n * Check if a path should be excluded from logging\n */\nfunction shouldExclude(path: string, excludePaths: Set<string>): boolean {\n // Direct match\n if (excludePaths.has(path)) {\n return true;\n }\n\n // Prefix match for GateOps routes\n for (const excluded of excludePaths) {\n if (path.startsWith(excluded)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Create a sanitized log entry from request/response\n */\nfunction createLogEntry(\n req: Request,\n res: Response,\n traceId: string,\n duration: number,\n responseBody: string,\n maxBodySize: number,\n sensitiveFields: string[]\n): TrafficLog {\n // Parse and sanitize request body\n let reqBody: unknown = req.body;\n if (typeof reqBody === 'object') {\n reqBody = sanitize(reqBody, maxBodySize, sensitiveFields);\n }\n\n // Parse and sanitize response body\n let resBody: unknown;\n try {\n resBody = JSON.parse(responseBody);\n resBody = sanitize(resBody, maxBodySize, sensitiveFields);\n } catch {\n // Not JSON, truncate if too long\n resBody = responseBody.length > maxBodySize\n ? responseBody.substring(0, maxBodySize) + '...[truncated]'\n : responseBody;\n }\n\n // Get client IP\n const ip = req.ip ||\n req.headers['x-forwarded-for']?.toString().split(',')[0] ||\n req.socket?.remoteAddress ||\n 'unknown';\n\n return {\n trace_id: traceId,\n endpoint: req.path,\n method: req.method,\n status: res.statusCode,\n duration_ms: duration,\n req_headers: safeStringify(sanitizeHeaders(req.headers as Record<string, string>)),\n res_headers: safeStringify(sanitizeHeaders(res.getHeaders() as Record<string, string>)),\n req_body: safeStringify(reqBody, maxBodySize),\n res_body: safeStringify(resBody, maxBodySize),\n query_params: safeStringify(req.query),\n ip_address: ip,\n user_agent: req.headers['user-agent'],\n created_at: new Date()\n };\n}\n\nexport default createMiddleware;\n","import { Router, Request, Response } from 'express';\nimport { SDK_DEFAULTS } from './config';\nimport { getDatabase, trafficLogs, endpoints, config } from './db';\nimport { desc, eq, and, gte, lte, like } from 'drizzle-orm';\n\n/**\n * GateOps Exposed Routes\n * \n * Routes exposed on the user's Express app for Panel to query.\n * All routes are prefixed with /.well-known/gateops/\n * \n * Authentication: x-gateops-username + x-gateops-api-key headers\n */\n\nconst router = Router();\n\n/**\n * Authentication middleware for exposed routes\n */\nfunction authenticate(req: Request, res: Response, next: Function): void {\n const username = req.headers['x-gateops-username'] as string;\n const apiKey = req.headers['x-gateops-api-key'] as string;\n\n const expectedUsername = process.env.GATEOPS_USERNAME;\n const expectedApiKey = process.env.GATEOPS_API_KEY;\n\n if (!expectedUsername || !expectedApiKey) {\n res.status(503).json({\n error: 'GateOps not configured',\n message: 'GATEOPS_USERNAME and GATEOPS_API_KEY must be set'\n });\n return;\n }\n\n if (username !== expectedUsername || apiKey !== expectedApiKey) {\n res.status(401).json({\n error: 'Unauthorized',\n message: 'Invalid credentials'\n });\n return;\n }\n\n next();\n}\n\n// Apply auth to all routes\nrouter.use(authenticate);\n\n/**\n * GET /.well-known/gateops/health\n * \n * Health check endpoint, returns SDK version and status\n */\nrouter.get('/health', (_req: Request, res: Response) => {\n res.json({\n status: 'ok',\n version: require('../package.json').version,\n timestamp: new Date().toISOString()\n });\n});\n\n/**\n * GET /.well-known/gateops/logs\n * \n * Fetch traffic logs with pagination and filters\n * \n * Query params:\n * - page: Page number (default: 1)\n * - limit: Items per page (default: 50, max: 100)\n * - status: Filter by status code\n * - method: Filter by HTTP method\n * - endpoint: Filter by endpoint (partial match)\n * - from: Filter from date (ISO string)\n * - to: Filter to date (ISO string)\n * - minDuration: Filter by minimum duration (ms)\n */\nrouter.get('/logs', async (req: Request, res: Response) => {\n try {\n const db = getDatabase();\n\n // Pagination\n const page = Math.max(1, parseInt(req.query.page as string) || 1);\n const limit = Math.min(100, Math.max(1, parseInt(req.query.limit as string) || 50));\n const offset = (page - 1) * limit;\n\n // Build base query\n let query = db.select().from(trafficLogs);\n\n // Apply filters\n const conditions = [];\n\n if (req.query.status) {\n conditions.push(eq(trafficLogs.status, parseInt(req.query.status as string)));\n }\n\n if (req.query.method) {\n conditions.push(eq(trafficLogs.method, (req.query.method as string).toUpperCase()));\n }\n\n if (req.query.endpoint) {\n conditions.push(like(trafficLogs.endpoint, `%${req.query.endpoint}%`));\n }\n\n if (req.query.from) {\n conditions.push(gte(trafficLogs.created_at, new Date(req.query.from as string)));\n }\n\n if (req.query.to) {\n conditions.push(lte(trafficLogs.created_at, new Date(req.query.to as string)));\n }\n\n if (req.query.minDuration) {\n conditions.push(gte(trafficLogs.duration_ms, parseInt(req.query.minDuration as string)));\n }\n\n // Execute query\n const results = await query\n .where(conditions.length > 0 ? and(...conditions) : undefined)\n .orderBy(desc(trafficLogs.created_at))\n .limit(limit)\n .offset(offset);\n\n // Get total count for pagination\n const countResult = await db\n .select({ count: trafficLogs.id })\n .from(trafficLogs)\n .where(conditions.length > 0 ? and(...conditions) : undefined);\n\n const total = countResult.length;\n\n res.json({\n logs: results,\n pagination: {\n page,\n limit,\n total,\n totalPages: Math.ceil(total / limit)\n }\n });\n } catch (error) {\n console.error('[GateOps] Error fetching logs:', error);\n res.status(500).json({ error: 'Failed to fetch logs' });\n }\n});\n\n/**\n * GET /.well-known/gateops/logs/:traceId\n * \n * Get a single log entry by trace ID\n */\nrouter.get('/logs/:traceId', async (req: Request, res: Response) => {\n try {\n const db = getDatabase();\n\n const result = await db\n .select()\n .from(trafficLogs)\n .where(eq(trafficLogs.trace_id, req.params.traceId))\n .limit(1);\n\n if (result.length === 0) {\n res.status(404).json({ error: 'Log not found' });\n return;\n }\n\n res.json(result[0]);\n } catch (error) {\n console.error('[GateOps] Error fetching log:', error);\n res.status(500).json({ error: 'Failed to fetch log' });\n }\n});\n\n/**\n * GET /.well-known/gateops/endpoints\n * \n * Get all discovered endpoints\n */\nrouter.get('/endpoints', async (_req: Request, res: Response) => {\n try {\n const db = getDatabase();\n\n const results = await db\n .select()\n .from(endpoints)\n .orderBy(endpoints.path);\n\n res.json({\n endpoints: results,\n total: results.length\n });\n } catch (error) {\n console.error('[GateOps] Error fetching endpoints:', error);\n res.status(500).json({ error: 'Failed to fetch endpoints' });\n }\n});\n\n/**\n * GET /.well-known/gateops/config\n * \n * Get SDK configuration\n */\nrouter.get('/config', async (_req: Request, res: Response) => {\n try {\n const db = getDatabase();\n\n const results = await db.select().from(config);\n\n // Convert to key-value object\n const configObj: Record<string, unknown> = {};\n for (const row of results) {\n try {\n configObj[row.key] = JSON.parse(row.value);\n } catch {\n configObj[row.key] = row.value;\n }\n }\n\n res.json({\n config: configObj,\n defaults: {\n bufferSize: SDK_DEFAULTS.BUFFER_MAX_SIZE,\n flushInterval: SDK_DEFAULTS.BUFFER_FLUSH_INTERVAL,\n maxBodySize: SDK_DEFAULTS.MAX_BODY_SIZE,\n logTtlDays: SDK_DEFAULTS.LOG_TTL_DAYS\n }\n });\n } catch (error) {\n console.error('[GateOps] Error fetching config:', error);\n res.status(500).json({ error: 'Failed to fetch config' });\n }\n});\n\n/**\n * GET /.well-known/gateops/stats\n * \n * Get basic statistics\n */\nrouter.get('/stats', async (_req: Request, res: Response) => {\n try {\n const db = getDatabase();\n\n // Get total logs\n const logsCount = await db.select().from(trafficLogs);\n\n // Get endpoints count\n const endpointsCount = await db.select().from(endpoints);\n\n // Get error rate (5xx responses)\n const errors = logsCount.filter(l => l.status >= 500);\n\n // Get average duration\n const avgDuration = logsCount.length > 0\n ? logsCount.reduce((sum, l) => sum + l.duration_ms, 0) / logsCount.length\n : 0;\n\n res.json({\n totalLogs: logsCount.length,\n totalEndpoints: endpointsCount.length,\n errorCount: errors.length,\n errorRate: logsCount.length > 0\n ? ((errors.length / logsCount.length) * 100).toFixed(2) + '%'\n : '0%',\n avgDurationMs: Math.round(avgDuration)\n });\n } catch (error) {\n console.error('[GateOps] Error fetching stats:', error);\n res.status(500).json({ error: 'Failed to fetch stats' });\n }\n});\n\nexport default router;\nexport { router as gateopsRouter };\n","import { Express, Router } from 'express';\nimport { getDatabase, endpoints } from './db';\nimport { EndpointInfo, RouteLayer, ExpressApp } from './types';\nimport { eq, and } from 'drizzle-orm';\n\n/**\n * Route Scanner - Discovery Engine\n * \n * Scans Express app router stack to extract all registered routes.\n * Runs on app startup to populate the endpoints table.\n */\n\n/**\n * Scan all routes from an Express app\n */\nexport function scanRoutes(app: Express | ExpressApp): EndpointInfo[] {\n const routes: EndpointInfo[] = [];\n\n const expressApp = app as ExpressApp;\n\n if (!expressApp._router) {\n console.warn('[GateOps] No router found on app. Routes will be discovered on first request.');\n return routes;\n }\n\n // Traverse the router stack\n traverseStack(expressApp._router.stack, '', routes);\n\n return routes;\n}\n\n/**\n * Recursively traverse router stack to extract routes\n */\nfunction traverseStack(\n stack: RouteLayer[],\n basePath: string,\n routes: EndpointInfo[]\n): void {\n for (const layer of stack) {\n if (layer.route) {\n // This is a route layer\n const routePath = joinPaths(basePath, layer.route.path);\n const methods = Object.keys(layer.route.methods)\n .filter(m => layer.route!.methods[m])\n .map(m => m.toUpperCase());\n\n // Get middleware names from route stack\n const middlewareNames = layer.route.stack\n .map(l => l.name)\n .filter(n => n && n !== '<anonymous>');\n\n for (const method of methods) {\n routes.push({\n path: normalizePath(routePath),\n method,\n middleware_names: JSON.stringify(middlewareNames),\n last_seen: new Date()\n });\n }\n } else if (layer.name === 'router' && layer.handle) {\n // This is a nested router\n const routerPath = getLayerPath(layer);\n const nestedRouter = layer.handle as Router & { stack?: RouteLayer[] };\n\n if (nestedRouter.stack) {\n traverseStack(\n nestedRouter.stack,\n joinPaths(basePath, routerPath),\n routes\n );\n }\n }\n }\n}\n\n/**\n * Get the path from a router layer\n */\nfunction getLayerPath(layer: RouteLayer): string {\n if (layer.path) {\n return layer.path;\n }\n\n // Extract path from regexp\n if (layer.regexp) {\n const match = layer.regexp.toString().match(/^\\/\\^(.*?)\\\\\\//);\n if (match) {\n return match[1].replace(/\\\\\\//g, '/');\n }\n }\n\n return '';\n}\n\n/**\n * Join path segments\n */\nfunction joinPaths(base: string, path: string): string {\n if (!base) return path;\n if (!path) return base;\n\n const normalizedBase = base.endsWith('/') ? base.slice(0, -1) : base;\n const normalizedPath = path.startsWith('/') ? path : `/${path}`;\n\n return normalizedBase + normalizedPath;\n}\n\n/**\n * Normalize a path (handle params, etc.)\n */\nfunction normalizePath(path: string): string {\n // Replace Express param patterns like :id with {id}\n return path.replace(/:(\\w+)/g, '{$1}');\n}\n\n/**\n * Sync discovered routes to database\n */\nexport async function syncRoutesToDatabase(routes: EndpointInfo[]): Promise<void> {\n const db = getDatabase();\n const now = new Date();\n\n for (const route of routes) {\n try {\n // Try to update existing\n const existing = await db\n .select()\n .from(endpoints)\n .where(and(\n eq(endpoints.path, route.path),\n eq(endpoints.method, route.method)\n ))\n .limit(1);\n\n if (existing.length > 0) {\n // Update last_seen\n await db\n .update(endpoints)\n .set({\n last_seen: now,\n middleware_names: route.middleware_names\n })\n .where(and(\n eq(endpoints.path, route.path),\n eq(endpoints.method, route.method)\n ));\n } else {\n // Insert new\n await db.insert(endpoints).values({\n path: route.path,\n method: route.method,\n middleware_names: route.middleware_names,\n last_seen: now\n });\n }\n } catch (error) {\n console.error(`[GateOps] Failed to sync route ${route.method} ${route.path}:`, error);\n }\n }\n}\n\n/**\n * Update endpoint schema based on observed request/response\n */\nexport async function updateEndpointSchema(\n path: string,\n method: string,\n reqSchema: unknown,\n resSchema: unknown\n): Promise<void> {\n const db = getDatabase();\n\n try {\n const existing = await db\n .select()\n .from(endpoints)\n .where(and(\n eq(endpoints.path, path),\n eq(endpoints.method, method)\n ))\n .limit(1);\n\n const schema = {\n request: reqSchema,\n response: resSchema,\n inferredAt: new Date().toISOString()\n };\n\n if (existing.length > 0) {\n await db\n .update(endpoints)\n .set({\n detected_schema: JSON.stringify(schema),\n last_seen: new Date()\n })\n .where(and(\n eq(endpoints.path, path),\n eq(endpoints.method, method)\n ));\n } else {\n await db.insert(endpoints).values({\n path,\n method,\n detected_schema: JSON.stringify(schema),\n last_seen: new Date()\n });\n }\n } catch (error) {\n console.error(`[GateOps] Failed to update schema for ${method} ${path}:`, error);\n }\n}\n\n/**\n * Get all endpoints from database\n */\nexport async function getEndpoints(): Promise<EndpointInfo[]> {\n const db = getDatabase();\n const rows = await db.select().from(endpoints);\n\n return rows.map(row => ({\n id: row.id,\n path: row.path,\n method: row.method,\n detected_schema: row.detected_schema || undefined,\n middleware_names: row.middleware_names || undefined,\n last_seen: row.last_seen\n }));\n}\n","import axios from 'axios';\nimport { getPanelUrl, SDK_DEFAULTS } from './config';\nimport { TrafficLog, EndpointInfo, VerifyResponse, LogSubmitResponse } from './types';\n\n/**\n * Panel Sync Module\n * \n * Handles communication with the GateOps Panel API.\n */\n\n/**\n * Verify credentials with the Panel\n */\nexport async function verifyCredentials(\n username: string,\n apiKey: string\n): Promise<VerifyResponse> {\n try {\n const response = await axios.post<VerifyResponse>(\n getPanelUrl('VERIFY'),\n { username },\n {\n headers: {\n 'Content-Type': 'application/json',\n 'x-gateops-username': username,\n 'x-gateops-api-key': apiKey\n },\n timeout: 10000\n }\n );\n\n return response.data;\n } catch (error) {\n if (axios.isAxiosError(error)) {\n if (error.response?.status === 401) {\n return {\n success: false,\n message: 'Invalid credentials'\n };\n }\n return {\n success: false,\n message: error.message\n };\n }\n return {\n success: false,\n message: 'Connection failed'\n };\n }\n}\n\n/**\n * Send logs to the Panel\n */\nexport async function sendLogs(\n logs: TrafficLog[],\n username: string,\n apiKey: string,\n retryCount: number = 0\n): Promise<LogSubmitResponse> {\n try {\n const response = await axios.post<LogSubmitResponse>(\n getPanelUrl('LOGS'),\n {\n logs: logs.map(log => ({\n ...log,\n created_at: log.created_at instanceof Date\n ? log.created_at.toISOString()\n : log.created_at\n }))\n },\n {\n headers: {\n 'Content-Type': 'application/json',\n 'x-gateops-username': username,\n 'x-gateops-api-key': apiKey\n },\n timeout: 15000\n }\n );\n\n return response.data;\n } catch (error) {\n // Retry with exponential backoff\n if (retryCount < SDK_DEFAULTS.MAX_RETRY_ATTEMPTS) {\n const delay = SDK_DEFAULTS.RETRY_DELAY_BASE * Math.pow(2, retryCount);\n await sleep(delay);\n return sendLogs(logs, username, apiKey, retryCount + 1);\n }\n\n if (axios.isAxiosError(error)) {\n return {\n success: false,\n received: 0,\n message: error.message\n };\n }\n\n return {\n success: false,\n received: 0,\n message: 'Failed to send logs'\n };\n }\n}\n\n/**\n * Send discovered endpoints to the Panel\n */\nexport async function sendEndpoints(\n routes: EndpointInfo[],\n username: string,\n apiKey: string\n): Promise<boolean> {\n try {\n await axios.post(\n getPanelUrl('ENDPOINTS'),\n {\n endpoints: routes.map(r => ({\n path: r.path,\n method: r.method,\n detected_schema: r.detected_schema,\n middleware_names: r.middleware_names,\n last_seen: r.last_seen instanceof Date\n ? r.last_seen.toISOString()\n : r.last_seen\n }))\n },\n {\n headers: {\n 'Content-Type': 'application/json',\n 'x-gateops-username': username,\n 'x-gateops-api-key': apiKey\n },\n timeout: 10000\n }\n );\n\n return true;\n } catch (error) {\n console.warn('[GateOps] Failed to send endpoints to Panel:',\n axios.isAxiosError(error) ? error.message : error\n );\n return false;\n }\n}\n\n/**\n * Send heartbeat to Panel\n */\nexport async function sendHeartbeat(\n username: string,\n apiKey: string\n): Promise<boolean> {\n try {\n await axios.post(\n getPanelUrl('HEARTBEAT'),\n {\n timestamp: new Date().toISOString(),\n sdkVersion: require('../package.json').version\n },\n {\n headers: {\n 'Content-Type': 'application/json',\n 'x-gateops-username': username,\n 'x-gateops-api-key': apiKey\n },\n timeout: 5000\n }\n );\n\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Sleep helper\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n","/**\n * GateOps SDK - Lightweight API Observability for Express.js\n * \n * @packageDocumentation\n * \n * @example\n * ```typescript\n * import gateops from 'gateops-core';\n * \n * const app = express();\n * \n * // Initialize GateOps middleware\n * app.use(gateops.init());\n * \n * // Your routes...\n * app.get('/api/users', (req, res) => { ... });\n * \n * app.listen(3000);\n * ```\n */\n\nimport { Express } from 'express';\nimport createMiddleware from './middleware';\nimport { gateopsRouter } from './routes';\nimport { scanRoutes, syncRoutesToDatabase } from './scanner';\nimport { SDK_DEFAULTS } from './config';\nimport { GateOpsOptions, ExpressApp } from './types';\nimport { buffer } from './buffer';\nimport { sendEndpoints } from './sync';\n\n// Track if routes have been scanned\nlet routesScanned = false;\n\n/**\n * Initialize GateOps SDK\n * \n * Returns an Express middleware that captures all API traffic.\n * \n * @param options - Configuration options\n * @returns Express middleware function\n * \n * @example\n * ```typescript\n * // Basic usage\n * app.use(gateops.init());\n * \n * // With options\n * app.use(gateops.init({\n * excludePaths: ['/health', '/metrics'],\n * sensitiveFields: ['customSecret'],\n * localOnly: true // Don't send to Panel\n * }));\n * ```\n */\nfunction init(options: GateOpsOptions = {}) {\n const middleware = createMiddleware(options);\n\n // Return wrapped middleware that also mounts routes\n return function gateopsInit(req: any, res: any, next: any) {\n // Mount exposed routes on first request (if enabled)\n if (options.exposeRoutes !== false && req.app && !req.app._gateopsRoutesRegistered) {\n req.app.use(SDK_DEFAULTS.ROUTE_PREFIX, gateopsRouter);\n req.app._gateopsRoutesRegistered = true;\n }\n\n return middleware(req, res, next);\n };\n}\n\n/**\n * Scan and register all routes from an Express app\n * \n * Call this after all routes are registered, typically\n * right before `app.listen()`.\n * \n * @param app - Express application instance\n * \n * @example\n * ```typescript\n * // Register routes first\n * app.use('/api', apiRouter);\n * \n * // Then scan\n * gateops.scan(app);\n * \n * app.listen(3000);\n * ```\n */\nasync function scan(app: Express): Promise<void> {\n if (routesScanned) {\n return;\n }\n\n const routes = scanRoutes(app as unknown as ExpressApp);\n\n if (routes.length === 0) {\n console.warn('[GateOps] No routes found. Make sure to call scan() after registering routes.');\n return;\n }\n\n console.log(`[GateOps] Discovered ${routes.length} routes`);\n\n // Sync to local database\n await syncRoutesToDatabase(routes);\n\n // Send to Panel (if credentials are set)\n const username = process.env.GATEOPS_USERNAME;\n const apiKey = process.env.GATEOPS_API_KEY;\n\n if (username && apiKey) {\n await sendEndpoints(routes, username, apiKey);\n }\n\n routesScanned = true;\n}\n\n/**\n * Manually flush the log buffer\n * \n * Useful for testing or before graceful shutdown.\n */\nasync function flush(): Promise<void> {\n await buffer.flush();\n}\n\n/**\n * Shutdown GateOps SDK\n * \n * Call this before application exit for graceful shutdown.\n */\nfunction shutdown(): void {\n buffer.shutdown();\n}\n\n// Main export object\nconst gateops = {\n init,\n scan,\n flush,\n shutdown\n};\n\n// Exports\nexport default gateops;\nexport { init, scan, flush, shutdown };\n\n// Export types\nexport type { GateOpsOptions, TrafficLog, EndpointInfo } from './types';\n\n// Export utilities for advanced usage\nexport { sanitize, safeStringify, sanitizeHeaders } from './sanitizer';\nexport { getDatabase, initializeSchema, closeDatabase, cleanupOldLogs } from './db';\nexport { scanRoutes, syncRoutesToDatabase, getEndpoints } from './scanner';\nexport { verifyCredentials, sendLogs, sendEndpoints } from './sync';\nexport { buffer } from './buffer';\nexport { gateopsRouter } from './routes';\nexport { SDK_DEFAULTS, PANEL_ENDPOINTS, getPanelUrl } from './config';\n"]}