@objectstack/core 1.0.12 → 2.0.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.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/kernel-base.ts","../src/utils/env.ts","../src/logger.ts","../src/kernel.ts","../src/security/plugin-config-validator.ts","../src/plugin-loader.ts","../src/lite-kernel.ts","../src/api-registry.ts","../src/api-registry-plugin.ts","../src/qa/index.ts","../src/qa/runner.ts","../src/qa/http-adapter.ts","../src/security/plugin-signature-verifier.ts","../src/security/plugin-permission-enforcer.ts","../src/security/permission-manager.ts","../src/security/sandbox-runtime.ts","../src/security/security-scanner.ts","../src/health-monitor.ts","../src/hot-reload.ts","../src/dependency-resolver.ts"],"sourcesContent":["import type { Plugin, PluginContext } from './types.js';\nimport type { Logger } from '@objectstack/spec/contracts';\nimport type { IServiceRegistry } from '@objectstack/spec/contracts';\n\n/**\n * Kernel state machine\n */\nexport type KernelState = 'idle' | 'initializing' | 'running' | 'stopping' | 'stopped';\n\n/**\n * ObjectKernelBase - Abstract Base Class for Microkernel\n * \n * Provides common functionality for ObjectKernel and LiteKernel:\n * - Plugin management (Map storage)\n * - Dependency resolution (topological sort)\n * - Hook/Event system\n * - Context creation\n * - State validation\n * \n * This eliminates code duplication between the implementations.\n */\nexport abstract class ObjectKernelBase {\n protected plugins: Map<string, Plugin> = new Map();\n protected services: IServiceRegistry | Map<string, any> = new Map();\n protected hooks: Map<string, Array<(...args: any[]) => void | Promise<void>>> = new Map();\n protected state: KernelState = 'idle';\n protected logger: Logger;\n protected context!: PluginContext;\n\n constructor(logger: Logger) {\n this.logger = logger;\n }\n\n /**\n * Validate kernel state\n * @param requiredState - Required state for the operation\n * @throws Error if current state doesn't match\n */\n protected validateState(requiredState: KernelState): void {\n if (this.state !== requiredState) {\n throw new Error(\n `[Kernel] Invalid state: expected '${requiredState}', got '${this.state}'`\n );\n }\n }\n\n /**\n * Validate kernel is in idle state (for plugin registration)\n */\n protected validateIdle(): void {\n if (this.state !== 'idle') {\n throw new Error('[Kernel] Cannot register plugins after bootstrap has started');\n }\n }\n\n /**\n * Create the plugin context\n * Subclasses can override to customize context creation\n */\n protected createContext(): PluginContext {\n return {\n registerService: (name, service) => {\n if (this.services instanceof Map) {\n if (this.services.has(name)) {\n throw new Error(`[Kernel] Service '${name}' already registered`);\n }\n this.services.set(name, service);\n } else {\n // IServiceRegistry implementation\n this.services.register(name, service);\n }\n this.logger.info(`Service '${name}' registered`, { service: name });\n },\n getService: <T>(name: string): T => {\n if (this.services instanceof Map) {\n const service = this.services.get(name);\n if (!service) {\n throw new Error(`[Kernel] Service '${name}' not found`);\n }\n return service as T;\n } else {\n // IServiceRegistry implementation\n return this.services.get<T>(name);\n }\n },\n hook: (name, handler) => {\n if (!this.hooks.has(name)) {\n this.hooks.set(name, []);\n }\n this.hooks.get(name)!.push(handler);\n },\n trigger: async (name, ...args) => {\n const handlers = this.hooks.get(name) || [];\n for (const handler of handlers) {\n await handler(...args);\n }\n },\n getServices: () => {\n if (this.services instanceof Map) {\n return new Map(this.services);\n } else {\n // For IServiceRegistry, we need to return the underlying Map\n // This is a compatibility method\n return new Map();\n }\n },\n logger: this.logger,\n getKernel: () => this as any,\n };\n }\n\n /**\n * Resolve plugin dependencies using topological sort\n * @returns Ordered list of plugins (dependencies first)\n */\n protected resolveDependencies(): Plugin[] {\n const resolved: Plugin[] = [];\n const visited = new Set<string>();\n const visiting = new Set<string>();\n\n const visit = (pluginName: string) => {\n if (visited.has(pluginName)) return;\n \n if (visiting.has(pluginName)) {\n throw new Error(`[Kernel] Circular dependency detected: ${pluginName}`);\n }\n\n const plugin = this.plugins.get(pluginName);\n if (!plugin) {\n throw new Error(`[Kernel] Plugin '${pluginName}' not found`);\n }\n\n visiting.add(pluginName);\n\n // Visit dependencies first\n const deps = plugin.dependencies || [];\n for (const dep of deps) {\n if (!this.plugins.has(dep)) {\n throw new Error(\n `[Kernel] Dependency '${dep}' not found for plugin '${pluginName}'`\n );\n }\n visit(dep);\n }\n\n visiting.delete(pluginName);\n visited.add(pluginName);\n resolved.push(plugin);\n };\n\n // Visit all plugins\n for (const pluginName of this.plugins.keys()) {\n visit(pluginName);\n }\n\n return resolved;\n }\n\n /**\n * Run plugin init phase\n * @param plugin - Plugin to initialize\n */\n protected async runPluginInit(plugin: Plugin): Promise<void> {\n const pluginName = plugin.name;\n this.logger.info(`Initializing plugin: ${pluginName}`);\n \n try {\n await plugin.init(this.context);\n this.logger.info(`Plugin initialized: ${pluginName}`);\n } catch (error) {\n this.logger.error(`Plugin init failed: ${pluginName}`, error as Error);\n throw error;\n }\n }\n\n /**\n * Run plugin start phase\n * @param plugin - Plugin to start\n */\n protected async runPluginStart(plugin: Plugin): Promise<void> {\n if (!plugin.start) return;\n \n const pluginName = plugin.name;\n this.logger.info(`Starting plugin: ${pluginName}`);\n \n try {\n await plugin.start(this.context);\n this.logger.info(`Plugin started: ${pluginName}`);\n } catch (error) {\n this.logger.error(`Plugin start failed: ${pluginName}`, error as Error);\n throw error;\n }\n }\n\n /**\n * Run plugin destroy phase\n * @param plugin - Plugin to destroy\n */\n protected async runPluginDestroy(plugin: Plugin): Promise<void> {\n if (!plugin.destroy) return;\n \n const pluginName = plugin.name;\n this.logger.info(`Destroying plugin: ${pluginName}`);\n \n try {\n await plugin.destroy();\n this.logger.info(`Plugin destroyed: ${pluginName}`);\n } catch (error) {\n this.logger.error(`Plugin destroy failed: ${pluginName}`, error as Error);\n throw error;\n }\n }\n\n /**\n * Trigger a hook with all registered handlers\n * @param name - Hook name\n * @param args - Arguments to pass to handlers\n */\n protected async triggerHook(name: string, ...args: any[]): Promise<void> {\n const handlers = this.hooks.get(name) || [];\n this.logger.debug(`Triggering hook: ${name}`, { \n hook: name, \n handlerCount: handlers.length \n });\n \n for (const handler of handlers) {\n try {\n await handler(...args);\n } catch (error) {\n this.logger.error(`Hook handler failed: ${name}`, error as Error);\n // Continue with other handlers even if one fails\n }\n }\n }\n\n /**\n * Get current kernel state\n */\n getState(): KernelState {\n return this.state;\n }\n\n /**\n * Get all registered plugins\n */\n getPlugins(): Map<string, Plugin> {\n return new Map(this.plugins);\n }\n\n /**\n * Abstract methods to be implemented by subclasses\n */\n abstract use(plugin: Plugin): this | Promise<this>;\n abstract bootstrap(): Promise<void>;\n abstract destroy(): Promise<void>;\n}\n","/**\n * Environment utilities for universal (Node/Browser) compatibility.\n */\n\n// Check if running in a Node.js environment\nexport const isNode = typeof process !== 'undefined' && \n process.versions != null && \n process.versions.node != null;\n\n/**\n * Safely access environment variables\n */\nexport function getEnv(key: string, defaultValue?: string): string | undefined {\n // Node.js\n if (typeof process !== 'undefined' && process.env) {\n return process.env[key] || defaultValue;\n }\n \n // Browser (Vite/Webpack replacement usually handles process.env, \n // but if not, we check safe global access)\n try {\n // @ts-ignore\n if (typeof globalThis !== 'undefined' && globalThis.process?.env) {\n // @ts-ignore\n return globalThis.process.env[key] || defaultValue;\n }\n } catch (e) {\n // Ignore access errors\n }\n \n return defaultValue;\n}\n\n/**\n * Safely exit the process if in Node.js\n */\nexport function safeExit(code: number = 0): void {\n if (isNode) {\n process.exit(code);\n }\n}\n\n/**\n * Safely get memory usage\n */\nexport function getMemoryUsage(): { heapUsed: number; heapTotal: number } {\n if (isNode) {\n return process.memoryUsage();\n }\n return { heapUsed: 0, heapTotal: 0 };\n}\n","import type { LoggerConfig, LogLevel } from '@objectstack/spec/system';\nimport type { Logger } from '@objectstack/spec/contracts';\nimport { isNode } from './utils/env.js';\n\n/**\n * Universal Logger Implementation\n * \n * A configurable logger that works in both browser and Node.js environments.\n * - Node.js: Uses Pino for high-performance structured logging\n * - Browser: Simple console-based implementation\n * \n * Features:\n * - Structured logging with multiple formats (json, text, pretty)\n * - Log level filtering\n * - Sensitive data redaction\n * - File logging with rotation (Node.js only via Pino)\n * - Browser console integration\n * - Distributed tracing support (traceId, spanId)\n */\nexport class ObjectLogger implements Logger {\n private config: Required<Omit<LoggerConfig, 'file' | 'rotation' | 'name'>> & { file?: string; rotation?: { maxSize: string; maxFiles: number }; name?: string };\n private isNode: boolean;\n private pinoLogger?: any; // Pino logger instance for Node.js\n private pinoInstance?: any; // Base Pino instance for creating child loggers\n private require?: any; // CommonJS require function for Node.js\n\n constructor(config: Partial<LoggerConfig> = {}) {\n // Detect runtime environment\n this.isNode = isNode;\n\n // Set defaults\n this.config = {\n name: config.name,\n level: config.level ?? 'info',\n format: config.format ?? (this.isNode ? 'json' : 'pretty'),\n redact: config.redact ?? ['password', 'token', 'secret', 'key'],\n sourceLocation: config.sourceLocation ?? false,\n file: config.file,\n rotation: config.rotation ?? {\n maxSize: '10m',\n maxFiles: 5\n }\n };\n\n // Initialize Pino logger for Node.js\n if (this.isNode) {\n this.initPinoLogger();\n }\n }\n\n /**\n * Initialize Pino logger for Node.js\n */\n private async initPinoLogger() {\n if (!this.isNode) return;\n\n try {\n // Create require function dynamically for Node.js (avoids bundling issues in browser)\n // @ts-ignore - dynamic import of Node.js module\n const { createRequire } = await import('module');\n this.require = createRequire(import.meta.url);\n \n // Synchronous import for Pino using createRequire (works in ESM)\n const pino = this.require('pino');\n \n // Build Pino options\n const pinoOptions: any = {\n level: this.config.level,\n redact: {\n paths: this.config.redact,\n censor: '***REDACTED***'\n }\n };\n\n // Add name if provided\n if (this.config.name) {\n pinoOptions.name = this.config.name;\n }\n\n // Transport configuration for pretty printing or file output\n const targets: any[] = [];\n\n // Console transport\n if (this.config.format === 'pretty') {\n // Check if pino-pretty is available\n let hasPretty = false;\n try {\n this.require.resolve('pino-pretty');\n hasPretty = true;\n } catch (e) {\n // ignore\n }\n\n if (hasPretty) {\n targets.push({\n target: 'pino-pretty',\n options: {\n colorize: true,\n translateTime: 'SYS:standard',\n ignore: 'pid,hostname'\n },\n level: this.config.level\n });\n } else {\n console.warn('[Logger] pino-pretty not found. Install it for pretty logging: pnpm add -D pino-pretty');\n // Fallback to text/simple\n targets.push({\n target: 'pino/file',\n options: { destination: 1 },\n level: this.config.level\n });\n }\n } else if (this.config.format === 'json') {\n // JSON to stdout\n targets.push({\n target: 'pino/file',\n options: { destination: 1 }, // stdout\n level: this.config.level\n });\n } else {\n // text format (simple)\n targets.push({\n target: 'pino/file',\n options: { destination: 1 },\n level: this.config.level\n });\n }\n\n // File transport (if configured)\n if (this.config.file) {\n targets.push({\n target: 'pino/file',\n options: {\n destination: this.config.file,\n mkdir: true\n },\n level: this.config.level\n });\n }\n\n // Create transport\n if (targets.length > 0) {\n pinoOptions.transport = targets.length === 1 ? targets[0] : { targets };\n }\n\n // Create Pino logger\n this.pinoInstance = pino(pinoOptions);\n this.pinoLogger = this.pinoInstance;\n\n } catch (error) {\n // Fallback to console if Pino is not available\n console.warn('[Logger] Pino not available, falling back to console:', error);\n this.pinoLogger = null;\n }\n }\n\n /**\n * Redact sensitive keys from context object (for browser)\n */\n private redactSensitive(obj: any): any {\n if (!obj || typeof obj !== 'object') return obj;\n\n const redacted = Array.isArray(obj) ? [...obj] : { ...obj };\n\n for (const key in redacted) {\n const lowerKey = key.toLowerCase();\n const shouldRedact = this.config.redact.some((pattern: string) => \n lowerKey.includes(pattern.toLowerCase())\n );\n\n if (shouldRedact) {\n redacted[key] = '***REDACTED***';\n } else if (typeof redacted[key] === 'object' && redacted[key] !== null) {\n redacted[key] = this.redactSensitive(redacted[key]);\n }\n }\n\n return redacted;\n }\n\n /**\n * Format log entry for browser\n */\n private formatBrowserLog(level: LogLevel, message: string, context?: Record<string, any>): string {\n if (this.config.format === 'json') {\n return JSON.stringify({\n timestamp: new Date().toISOString(),\n level,\n message,\n ...context\n });\n }\n\n if (this.config.format === 'text') {\n const parts = [new Date().toISOString(), level.toUpperCase(), message];\n if (context && Object.keys(context).length > 0) {\n parts.push(JSON.stringify(context));\n }\n return parts.join(' | ');\n }\n\n // Pretty format\n const levelColors: Record<LogLevel, string> = {\n debug: '\\x1b[36m', // Cyan\n info: '\\x1b[32m', // Green\n warn: '\\x1b[33m', // Yellow\n error: '\\x1b[31m', // Red\n fatal: '\\x1b[35m', // Magenta\n silent: ''\n };\n const reset = '\\x1b[0m';\n const color = levelColors[level] || '';\n\n let output = `${color}[${level.toUpperCase()}]${reset} ${message}`;\n \n if (context && Object.keys(context).length > 0) {\n output += ` ${JSON.stringify(context, null, 2)}`;\n }\n\n return output;\n }\n\n /**\n * Log using browser console\n */\n private logBrowser(level: LogLevel, message: string, context?: Record<string, any>, error?: Error) {\n const redactedContext = context ? this.redactSensitive(context) : undefined;\n const mergedContext = error ? { ...redactedContext, error: { message: error.message, stack: error.stack } } : redactedContext;\n \n const formatted = this.formatBrowserLog(level, message, mergedContext);\n \n const consoleMethod = level === 'debug' ? 'debug' :\n level === 'info' ? 'log' :\n level === 'warn' ? 'warn' :\n level === 'error' || level === 'fatal' ? 'error' :\n 'log';\n \n console[consoleMethod](formatted);\n }\n\n /**\n * Public logging methods\n */\n debug(message: string, meta?: Record<string, any>): void {\n if (this.isNode && this.pinoLogger) {\n this.pinoLogger.debug(meta || {}, message);\n } else {\n this.logBrowser('debug', message, meta);\n }\n }\n\n info(message: string, meta?: Record<string, any>): void {\n if (this.isNode && this.pinoLogger) {\n this.pinoLogger.info(meta || {}, message);\n } else {\n this.logBrowser('info', message, meta);\n }\n }\n\n warn(message: string, meta?: Record<string, any>): void {\n if (this.isNode && this.pinoLogger) {\n this.pinoLogger.warn(meta || {}, message);\n } else {\n this.logBrowser('warn', message, meta);\n }\n }\n\n error(message: string, errorOrMeta?: Error | Record<string, any>, meta?: Record<string, any>): void {\n let error: Error | undefined;\n let context: Record<string, any> = {};\n\n if (errorOrMeta instanceof Error) {\n error = errorOrMeta;\n context = meta || {};\n } else {\n context = errorOrMeta || {};\n }\n\n if (this.isNode && this.pinoLogger) {\n const errorContext = error ? { err: error, ...context } : context;\n this.pinoLogger.error(errorContext, message);\n } else {\n this.logBrowser('error', message, context, error);\n }\n }\n\n fatal(message: string, errorOrMeta?: Error | Record<string, any>, meta?: Record<string, any>): void {\n let error: Error | undefined;\n let context: Record<string, any> = {};\n\n if (errorOrMeta instanceof Error) {\n error = errorOrMeta;\n context = meta || {};\n } else {\n context = errorOrMeta || {};\n }\n\n if (this.isNode && this.pinoLogger) {\n const errorContext = error ? { err: error, ...context } : context;\n this.pinoLogger.fatal(errorContext, message);\n } else {\n this.logBrowser('fatal', message, context, error);\n }\n }\n\n /**\n * Create a child logger with additional context\n * Note: Child loggers share the parent's Pino instance\n */\n child(context: Record<string, any>): ObjectLogger {\n const childLogger = new ObjectLogger(this.config);\n \n // For Node.js with Pino, create a Pino child logger\n if (this.isNode && this.pinoInstance) {\n childLogger.pinoLogger = this.pinoInstance.child(context);\n childLogger.pinoInstance = this.pinoInstance;\n }\n\n return childLogger;\n }\n\n /**\n * Set trace context for distributed tracing\n */\n withTrace(traceId: string, spanId?: string): ObjectLogger {\n return this.child({ traceId, spanId });\n }\n\n /**\n * Cleanup resources\n */\n async destroy(): Promise<void> {\n if (this.pinoLogger && this.pinoLogger.flush) {\n await new Promise<void>((resolve) => {\n this.pinoLogger.flush(() => resolve());\n });\n }\n }\n\n /**\n * Compatibility method for console.log usage\n */\n log(message: string, ...args: any[]): void {\n this.info(message, args.length > 0 ? { args } : undefined);\n }\n}\n\n/**\n * Create a logger instance\n */\nexport function createLogger(config?: Partial<LoggerConfig>): ObjectLogger {\n return new ObjectLogger(config);\n}\n","import { Plugin, PluginContext } from './types.js';\nimport { createLogger, ObjectLogger } from './logger.js';\nimport type { LoggerConfig } from '@objectstack/spec/system';\nimport { ServiceRequirementDef } from '@objectstack/spec/system';\nimport { PluginLoader, PluginMetadata, ServiceLifecycle, ServiceFactory, PluginStartupResult } from './plugin-loader.js';\nimport { isNode, safeExit } from './utils/env.js';\n\n/**\n * Enhanced Kernel Configuration\n */\nexport interface ObjectKernelConfig {\n logger?: Partial<LoggerConfig>;\n \n /** Default plugin startup timeout in milliseconds */\n defaultStartupTimeout?: number;\n \n /** Whether to enable graceful shutdown */\n gracefulShutdown?: boolean;\n \n /** Graceful shutdown timeout in milliseconds */\n shutdownTimeout?: number;\n \n /** Whether to rollback on startup failure */\n rollbackOnFailure?: boolean;\n \n /** Whether to skip strict system requirement validation (Critical for testing) */\n skipSystemValidation?: boolean;\n}\n\n/**\n * Enhanced ObjectKernel with Advanced Plugin Management\n * \n * Extends the basic ObjectKernel with:\n * - Async plugin loading with validation\n * - Version compatibility checking\n * - Plugin signature verification\n * - Configuration validation (Zod)\n * - Factory-based dependency injection\n * - Service lifecycle management (singleton/transient/scoped)\n * - Circular dependency detection\n * - Lazy loading services\n * - Graceful shutdown\n * - Plugin startup timeout control\n * - Startup failure rollback\n * - Plugin health checks\n */\nexport class ObjectKernel {\n private plugins: Map<string, PluginMetadata> = new Map();\n private services: Map<string, any> = new Map();\n private hooks: Map<string, Array<(...args: any[]) => void | Promise<void>>> = new Map();\n private state: 'idle' | 'initializing' | 'running' | 'stopping' | 'stopped' = 'idle';\n private logger: ObjectLogger;\n private context: PluginContext;\n private pluginLoader: PluginLoader;\n private config: ObjectKernelConfig;\n private startedPlugins: Set<string> = new Set();\n private pluginStartTimes: Map<string, number> = new Map();\n private shutdownHandlers: Array<() => Promise<void>> = [];\n\n constructor(config: ObjectKernelConfig = {}) {\n this.config = {\n defaultStartupTimeout: 30000, // 30 seconds\n gracefulShutdown: true,\n shutdownTimeout: 60000, // 60 seconds\n rollbackOnFailure: true,\n ...config,\n };\n\n this.logger = createLogger(config.logger);\n this.pluginLoader = new PluginLoader(this.logger);\n \n // Initialize context\n this.context = {\n registerService: (name, service) => {\n this.registerService(name, service);\n },\n getService: <T>(name: string) => {\n // 1. Try direct service map first (synchronous cache)\n const service = this.services.get(name);\n if (service) {\n return service as T;\n }\n\n // 2. Try to get from plugin loader cache (Sync access to factories)\n const loaderService = this.pluginLoader.getServiceInstance<T>(name);\n if (loaderService) {\n // Cache it locally for faster next access\n this.services.set(name, loaderService);\n return loaderService;\n }\n\n // 3. Try to get from plugin loader (support async factories)\n try {\n const service = this.pluginLoader.getService(name);\n if (service instanceof Promise) {\n // If we found it in the loader but not in the sync map, it's likely a factory-based service or still loading\n // We must silence any potential rejection from this promise since we are about to throw our own error\n // and abandon the promise. Without this, Node.js will crash with \"Unhandled Promise Rejection\".\n service.catch(() => {});\n throw new Error(`Service '${name}' is async - use await`);\n }\n return service as T;\n } catch (error: any) {\n if (error.message?.includes('is async')) {\n throw error;\n }\n \n // Re-throw critical factory errors instead of masking them as \"not found\"\n // If the error came from the factory execution (e.g. database connection failed), we must see it.\n // \"Service '${name}' not found\" comes from PluginLoader.getService fallback.\n const isNotFoundError = error.message === `Service '${name}' not found`;\n \n if (!isNotFoundError) {\n throw error;\n }\n\n throw new Error(`[Kernel] Service '${name}' not found`);\n }\n },\n hook: (name, handler) => {\n if (!this.hooks.has(name)) {\n this.hooks.set(name, []);\n }\n this.hooks.get(name)!.push(handler);\n },\n trigger: async (name, ...args) => {\n const handlers = this.hooks.get(name) || [];\n for (const handler of handlers) {\n await handler(...args);\n }\n },\n getServices: () => {\n return new Map(this.services);\n },\n logger: this.logger,\n getKernel: () => this as any, // Type compatibility\n };\n\n this.pluginLoader.setContext(this.context);\n\n // Register shutdown handler\n if (this.config.gracefulShutdown) {\n this.registerShutdownSignals();\n }\n }\n\n /**\n * Register a plugin with enhanced validation\n */\n async use(plugin: Plugin): Promise<this> {\n if (this.state !== 'idle') {\n throw new Error('[Kernel] Cannot register plugins after bootstrap has started');\n }\n\n // Load plugin through enhanced loader\n const result = await this.pluginLoader.loadPlugin(plugin);\n \n if (!result.success || !result.plugin) {\n throw new Error(`Failed to load plugin: ${plugin.name} - ${result.error?.message}`);\n }\n\n const pluginMeta = result.plugin;\n this.plugins.set(pluginMeta.name, pluginMeta);\n \n this.logger.info(`Plugin registered: ${pluginMeta.name}@${pluginMeta.version}`, {\n plugin: pluginMeta.name,\n version: pluginMeta.version,\n });\n\n return this;\n }\n\n /**\n * Register a service instance directly\n */\n registerService<T>(name: string, service: T): this {\n if (this.services.has(name)) {\n throw new Error(`[Kernel] Service '${name}' already registered`);\n }\n this.services.set(name, service);\n this.pluginLoader.registerService(name, service);\n this.logger.info(`Service '${name}' registered`, { service: name });\n return this;\n }\n\n /**\n * Register a service factory with lifecycle management\n */\n registerServiceFactory<T>(\n name: string,\n factory: ServiceFactory<T>,\n lifecycle: ServiceLifecycle = ServiceLifecycle.SINGLETON,\n dependencies?: string[]\n ): this {\n this.pluginLoader.registerServiceFactory({\n name,\n factory,\n lifecycle,\n dependencies,\n });\n return this;\n }\n\n /**\n * Validate Critical System Requirements\n */\n private validateSystemRequirements() {\n if (this.config.skipSystemValidation) {\n this.logger.debug('System requirement validation skipped');\n return;\n }\n\n this.logger.debug('Validating system service requirements...');\n const missingServices: string[] = [];\n const missingCoreServices: string[] = [];\n \n // Iterate through all defined requirements\n for (const [serviceName, criticality] of Object.entries(ServiceRequirementDef)) {\n const hasService = this.services.has(serviceName) || this.pluginLoader.hasService(serviceName);\n \n if (!hasService) {\n if (criticality === 'required') {\n this.logger.error(`CRITICAL: Required service missing: ${serviceName}`);\n missingServices.push(serviceName);\n } else if (criticality === 'core') {\n this.logger.warn(`CORE: Core service missing, functionality may be degraded: ${serviceName}`);\n missingCoreServices.push(serviceName);\n } else {\n this.logger.info(`Info: Optional service not present: ${serviceName}`);\n }\n }\n }\n\n if (missingServices.length > 0) {\n const errorMsg = `System failed to start. Missing critical services: ${missingServices.join(', ')}`;\n this.logger.error(errorMsg);\n throw new Error(errorMsg);\n }\n\n if (missingCoreServices.length > 0) {\n this.logger.warn(`System started with degraded capabilities. Missing core services: ${missingCoreServices.join(', ')}`);\n }\n \n this.logger.info('System requirement check passed');\n }\n\n /**\n * Bootstrap the kernel with enhanced features\n */\n async bootstrap(): Promise<void> {\n if (this.state !== 'idle') {\n throw new Error('[Kernel] Kernel already bootstrapped');\n }\n\n this.state = 'initializing';\n this.logger.info('Bootstrap started');\n\n try {\n // Check for circular dependencies\n const cycles = this.pluginLoader.detectCircularDependencies();\n if (cycles.length > 0) {\n this.logger.warn('Circular service dependencies detected:', { cycles });\n }\n\n // Resolve plugin dependencies\n const orderedPlugins = this.resolveDependencies();\n\n // Phase 1: Init - Plugins register services\n this.logger.info('Phase 1: Init plugins');\n for (const plugin of orderedPlugins) {\n await this.initPluginWithTimeout(plugin);\n }\n\n // Phase 2: Start - Plugins execute business logic\n this.logger.info('Phase 2: Start plugins');\n this.state = 'running';\n \n for (const plugin of orderedPlugins) {\n const result = await this.startPluginWithTimeout(plugin);\n \n if (!result.success) {\n this.logger.error(`Plugin startup failed: ${plugin.name}`, result.error);\n \n if (this.config.rollbackOnFailure) {\n this.logger.warn('Rolling back started plugins...');\n await this.rollbackStartedPlugins();\n throw new Error(`Plugin ${plugin.name} failed to start - rollback complete`);\n }\n }\n }\n\n // Phase 3: Trigger kernel:ready hook\n this.validateSystemRequirements(); // Final check before ready\n this.logger.debug('Triggering kernel:ready hook');\n await this.context.trigger('kernel:ready');\n\n this.logger.info('✅ Bootstrap complete');\n } catch (error) {\n this.state = 'stopped';\n throw error;\n }\n }\n\n /**\n * Graceful shutdown with timeout\n */\n async shutdown(): Promise<void> {\n if (this.state === 'stopped' || this.state === 'stopping') {\n this.logger.warn('Kernel already stopped or stopping');\n return;\n }\n\n if (this.state !== 'running') {\n throw new Error('[Kernel] Kernel not running');\n }\n\n this.state = 'stopping';\n this.logger.info('Graceful shutdown started');\n\n try {\n // Create shutdown promise with timeout\n const shutdownPromise = this.performShutdown();\n const timeoutPromise = new Promise<void>((_, reject) => {\n setTimeout(() => {\n reject(new Error('Shutdown timeout exceeded'));\n }, this.config.shutdownTimeout);\n });\n\n // Race between shutdown and timeout\n await Promise.race([shutdownPromise, timeoutPromise]);\n\n this.state = 'stopped';\n this.logger.info('✅ Graceful shutdown complete');\n } catch (error) {\n this.logger.error('Shutdown error - forcing stop', error as Error);\n this.state = 'stopped';\n throw error;\n } finally {\n // Cleanup logger resources\n await this.logger.destroy();\n }\n }\n\n /**\n * Check health of a specific plugin\n */\n async checkPluginHealth(pluginName: string): Promise<any> {\n return await this.pluginLoader.checkPluginHealth(pluginName);\n }\n\n /**\n * Check health of all plugins\n */\n async checkAllPluginsHealth(): Promise<Map<string, any>> {\n const results = new Map();\n \n for (const pluginName of this.plugins.keys()) {\n const health = await this.checkPluginHealth(pluginName);\n results.set(pluginName, health);\n }\n \n return results;\n }\n\n /**\n * Get plugin startup metrics\n */\n getPluginMetrics(): Map<string, number> {\n return new Map(this.pluginStartTimes);\n }\n\n /**\n * Get a service (sync helper)\n */\n getService<T>(name: string): T {\n return this.context.getService<T>(name);\n }\n\n /**\n * Get a service asynchronously (supports factories)\n */\n async getServiceAsync<T>(name: string, scopeId?: string): Promise<T> {\n return await this.pluginLoader.getService<T>(name, scopeId);\n }\n\n /**\n * Check if kernel is running\n */\n isRunning(): boolean {\n return this.state === 'running';\n }\n\n /**\n * Get kernel state\n */\n getState(): string {\n return this.state;\n }\n\n // Private methods\n\n private async initPluginWithTimeout(plugin: PluginMetadata): Promise<void> {\n const timeout = plugin.startupTimeout || this.config.defaultStartupTimeout!;\n \n this.logger.debug(`Init: ${plugin.name}`, { plugin: plugin.name });\n \n const initPromise = plugin.init(this.context);\n const timeoutPromise = new Promise<void>((_, reject) => {\n setTimeout(() => {\n reject(new Error(`Plugin ${plugin.name} init timeout after ${timeout}ms`));\n }, timeout);\n });\n\n await Promise.race([initPromise, timeoutPromise]);\n }\n\n private async startPluginWithTimeout(plugin: PluginMetadata): Promise<PluginStartupResult> {\n if (!plugin.start) {\n return { success: true, pluginName: plugin.name };\n }\n\n const timeout = plugin.startupTimeout || this.config.defaultStartupTimeout!;\n const startTime = Date.now();\n \n this.logger.debug(`Start: ${plugin.name}`, { plugin: plugin.name });\n \n try {\n const startPromise = plugin.start(this.context);\n const timeoutPromise = new Promise<void>((_, reject) => {\n setTimeout(() => {\n reject(new Error(`Plugin ${plugin.name} start timeout after ${timeout}ms`));\n }, timeout);\n });\n\n await Promise.race([startPromise, timeoutPromise]);\n \n const duration = Date.now() - startTime;\n this.startedPlugins.add(plugin.name);\n this.pluginStartTimes.set(plugin.name, duration);\n \n this.logger.debug(`Plugin started: ${plugin.name} (${duration}ms)`);\n \n return {\n success: true,\n pluginName: plugin.name,\n startTime: duration,\n };\n } catch (error) {\n const duration = Date.now() - startTime;\n const isTimeout = (error as Error).message.includes('timeout');\n \n return {\n success: false,\n pluginName: plugin.name,\n error: error as Error,\n startTime: duration,\n timedOut: isTimeout,\n };\n }\n }\n\n private async rollbackStartedPlugins(): Promise<void> {\n const pluginsToRollback = Array.from(this.startedPlugins).reverse();\n \n for (const pluginName of pluginsToRollback) {\n const plugin = this.plugins.get(pluginName);\n if (plugin?.destroy) {\n try {\n this.logger.debug(`Rollback: ${pluginName}`);\n await plugin.destroy();\n } catch (error) {\n this.logger.error(`Rollback failed for ${pluginName}`, error as Error);\n }\n }\n }\n \n this.startedPlugins.clear();\n }\n\n private async performShutdown(): Promise<void> {\n // Trigger shutdown hook\n await this.context.trigger('kernel:shutdown');\n\n // Destroy plugins in reverse order\n const orderedPlugins = Array.from(this.plugins.values()).reverse();\n for (const plugin of orderedPlugins) {\n if (plugin.destroy) {\n this.logger.debug(`Destroy: ${plugin.name}`, { plugin: plugin.name });\n try {\n await plugin.destroy();\n } catch (error) {\n this.logger.error(`Error destroying plugin ${plugin.name}`, error as Error);\n }\n }\n }\n\n // Execute custom shutdown handlers\n for (const handler of this.shutdownHandlers) {\n try {\n await handler();\n } catch (error) {\n this.logger.error('Shutdown handler error', error as Error);\n }\n }\n }\n\n private resolveDependencies(): PluginMetadata[] {\n const resolved: PluginMetadata[] = [];\n const visited = new Set<string>();\n const visiting = new Set<string>();\n\n const visit = (pluginName: string) => {\n if (visited.has(pluginName)) return;\n \n if (visiting.has(pluginName)) {\n throw new Error(`[Kernel] Circular dependency detected: ${pluginName}`);\n }\n\n const plugin = this.plugins.get(pluginName);\n if (!plugin) {\n throw new Error(`[Kernel] Plugin '${pluginName}' not found`);\n }\n\n visiting.add(pluginName);\n\n // Visit dependencies first\n const deps = plugin.dependencies || [];\n for (const dep of deps) {\n if (!this.plugins.has(dep)) {\n throw new Error(`[Kernel] Dependency '${dep}' not found for plugin '${pluginName}'`);\n }\n visit(dep);\n }\n\n visiting.delete(pluginName);\n visited.add(pluginName);\n resolved.push(plugin);\n };\n\n // Visit all plugins\n for (const pluginName of this.plugins.keys()) {\n visit(pluginName);\n }\n\n return resolved;\n }\n\n private registerShutdownSignals(): void {\n const signals: NodeJS.Signals[] = ['SIGINT', 'SIGTERM', 'SIGQUIT'];\n let shutdownInProgress = false;\n \n const handleShutdown = async (signal: string) => {\n if (shutdownInProgress) {\n this.logger.warn(`Shutdown already in progress, ignoring ${signal}`);\n return;\n }\n \n shutdownInProgress = true;\n this.logger.info(`Received ${signal} - initiating graceful shutdown`);\n \n try {\n await this.shutdown();\n safeExit(0);\n } catch (error) {\n this.logger.error('Shutdown failed', error as Error);\n safeExit(1);\n }\n };\n \n if (isNode) {\n for (const signal of signals) {\n process.on(signal, () => handleShutdown(signal));\n }\n }\n }\n\n /**\n * Register a custom shutdown handler\n */\n onShutdown(handler: () => Promise<void>): void {\n this.shutdownHandlers.push(handler);\n }\n}\n","import { z } from 'zod';\nimport type { Logger } from '@objectstack/spec/contracts';\nimport type { PluginMetadata } from '../plugin-loader.js';\n\n/**\n * Plugin Configuration Validator\n * \n * Validates plugin configurations against Zod schemas to ensure:\n * 1. Type safety - all config values have correct types\n * 2. Business rules - values meet constraints (min/max, regex, etc.)\n * 3. Required fields - all mandatory configuration is provided\n * 4. Default values - missing optional fields get defaults\n * \n * Architecture:\n * - Uses Zod for runtime validation\n * - Provides detailed error messages with field paths\n * - Supports nested configuration objects\n * - Allows partial validation for incremental updates\n * \n * Usage:\n * ```typescript\n * const validator = new PluginConfigValidator(logger);\n * const validConfig = validator.validatePluginConfig(plugin, userConfig);\n * ```\n */\nexport class PluginConfigValidator {\n private logger: Logger;\n \n constructor(logger: Logger) {\n this.logger = logger;\n }\n \n /**\n * Validate plugin configuration against its Zod schema\n * \n * @param plugin - Plugin metadata with configSchema\n * @param config - User-provided configuration\n * @returns Validated and typed configuration\n * @throws Error with detailed validation errors\n */\n validatePluginConfig<T = any>(plugin: PluginMetadata, config: any): T {\n if (!plugin.configSchema) {\n this.logger.debug(`Plugin ${plugin.name} has no config schema - skipping validation`);\n return config as T;\n }\n \n try {\n // Use Zod to parse and validate\n const validatedConfig = plugin.configSchema.parse(config);\n \n this.logger.debug(`✅ Plugin config validated: ${plugin.name}`, {\n plugin: plugin.name,\n configKeys: Object.keys(config || {}).length,\n });\n \n return validatedConfig as T;\n } catch (error) {\n if (error instanceof z.ZodError) {\n const formattedErrors = this.formatZodErrors(error);\n const errorMessage = [\n `Plugin ${plugin.name} configuration validation failed:`,\n ...formattedErrors.map(e => ` - ${e.path}: ${e.message}`),\n ].join('\\n');\n \n this.logger.error(errorMessage, undefined, {\n plugin: plugin.name,\n errors: formattedErrors,\n });\n \n throw new Error(errorMessage);\n }\n \n // Re-throw other errors\n throw error;\n }\n }\n \n /**\n * Validate partial configuration (for incremental updates)\n * \n * @param plugin - Plugin metadata\n * @param partialConfig - Partial configuration to validate\n * @returns Validated partial configuration\n */\n validatePartialConfig<T = any>(plugin: PluginMetadata, partialConfig: any): Partial<T> {\n if (!plugin.configSchema) {\n return partialConfig as Partial<T>;\n }\n \n try {\n // Use Zod's partial() method for partial validation\n // Cast to ZodObject to access partial() method\n const partialSchema = (plugin.configSchema as any).partial();\n const validatedConfig = partialSchema.parse(partialConfig);\n \n this.logger.debug(`✅ Partial config validated: ${plugin.name}`);\n return validatedConfig as Partial<T>;\n } catch (error) {\n if (error instanceof z.ZodError) {\n const formattedErrors = this.formatZodErrors(error);\n const errorMessage = [\n `Plugin ${plugin.name} partial configuration validation failed:`,\n ...formattedErrors.map(e => ` - ${e.path}: ${e.message}`),\n ].join('\\n');\n \n throw new Error(errorMessage);\n }\n \n throw error;\n }\n }\n \n /**\n * Get default configuration from schema\n * \n * @param plugin - Plugin metadata\n * @returns Default configuration object\n */\n getDefaultConfig<T = any>(plugin: PluginMetadata): T | undefined {\n if (!plugin.configSchema) {\n return undefined;\n }\n \n try {\n // Parse empty object to get defaults\n const defaults = plugin.configSchema.parse({});\n this.logger.debug(`Default config extracted: ${plugin.name}`);\n return defaults as T;\n } catch (error) {\n // Schema may require some fields - return undefined\n this.logger.debug(`No default config available: ${plugin.name}`);\n return undefined;\n }\n }\n \n /**\n * Check if configuration is valid without throwing\n * \n * @param plugin - Plugin metadata\n * @param config - Configuration to check\n * @returns True if valid, false otherwise\n */\n isConfigValid(plugin: PluginMetadata, config: any): boolean {\n if (!plugin.configSchema) {\n return true;\n }\n \n const result = plugin.configSchema.safeParse(config);\n return result.success;\n }\n \n /**\n * Get configuration errors without throwing\n * \n * @param plugin - Plugin metadata\n * @param config - Configuration to check\n * @returns Array of validation errors, or empty array if valid\n */\n getConfigErrors(plugin: PluginMetadata, config: any): Array<{path: string; message: string}> {\n if (!plugin.configSchema) {\n return [];\n }\n \n const result = plugin.configSchema.safeParse(config);\n \n if (result.success) {\n return [];\n }\n \n return this.formatZodErrors(result.error);\n }\n \n // Private methods\n \n private formatZodErrors(error: z.ZodError<any>): Array<{path: string; message: string}> {\n return error.issues.map((e: z.ZodIssue) => ({\n path: e.path.join('.') || 'root',\n message: e.message,\n }));\n }\n}\n\n/**\n * Create a plugin config validator\n * \n * @param logger - Logger instance\n * @returns Plugin config validator\n */\nexport function createPluginConfigValidator(logger: Logger): PluginConfigValidator {\n return new PluginConfigValidator(logger);\n}\n","import { Plugin, PluginContext } from './types.js';\nimport type { Logger } from '@objectstack/spec/contracts';\nimport { z } from 'zod';\nimport { PluginConfigValidator } from './security/plugin-config-validator.js';\n\n/**\n * Service Lifecycle Types\n * Defines how services are instantiated and managed\n */\nexport enum ServiceLifecycle {\n /** Single instance shared across all requests */\n SINGLETON = 'singleton',\n /** New instance created for each request */\n TRANSIENT = 'transient',\n /** New instance per scope (e.g., per HTTP request) */\n SCOPED = 'scoped',\n}\n\n/**\n * Service Factory\n * Function that creates a service instance\n */\nexport type ServiceFactory<T = any> = (ctx: PluginContext) => T | Promise<T>;\n\n/**\n * Service Registration Options\n */\nexport interface ServiceRegistration {\n name: string;\n factory: ServiceFactory;\n lifecycle: ServiceLifecycle;\n dependencies?: string[];\n}\n\n/**\n * Plugin Configuration Validator Interface\n * Uses Zod for runtime validation of plugin configurations\n * @deprecated Use the PluginConfigValidator class from security module instead\n */\nexport interface IPluginConfigValidator {\n schema: z.ZodSchema;\n validate(config: any): any;\n}\n\n/**\n * Plugin Metadata with Enhanced Features\n */\nexport interface PluginMetadata extends Plugin {\n /** Semantic version (e.g., \"1.0.0\") */\n version: string;\n \n /** Configuration schema for validation */\n configSchema?: z.ZodSchema;\n \n /** Plugin signature for security verification */\n signature?: string;\n \n /** Plugin health check function */\n healthCheck?(): Promise<PluginHealthStatus>;\n \n /** Startup timeout in milliseconds (default: 30000) */\n startupTimeout?: number;\n \n /** Whether plugin supports hot reload */\n hotReloadable?: boolean;\n}\n\n/**\n * Plugin Health Status\n */\nexport interface PluginHealthStatus {\n healthy: boolean;\n message?: string;\n details?: Record<string, any>;\n lastCheck?: Date;\n}\n\n/**\n * Plugin Load Result\n */\nexport interface PluginLoadResult {\n success: boolean;\n plugin?: PluginMetadata;\n error?: Error;\n loadTime?: number;\n}\n\n/**\n * Plugin Startup Result\n */\nexport interface PluginStartupResult {\n success: boolean;\n pluginName: string;\n startTime?: number;\n error?: Error;\n timedOut?: boolean;\n}\n\n/**\n * Version Compatibility Result\n */\nexport interface VersionCompatibility {\n compatible: boolean;\n pluginVersion: string;\n requiredVersion?: string;\n message?: string;\n}\n\n/**\n * Enhanced Plugin Loader\n * Provides advanced plugin loading capabilities with validation, security, and lifecycle management\n */\nexport class PluginLoader {\n private logger: Logger;\n private context?: PluginContext;\n private configValidator: PluginConfigValidator;\n private loadedPlugins: Map<string, PluginMetadata> = new Map();\n private serviceFactories: Map<string, ServiceRegistration> = new Map();\n private serviceInstances: Map<string, any> = new Map();\n private scopedServices: Map<string, Map<string, any>> = new Map();\n private creating: Set<string> = new Set();\n\n constructor(logger: Logger) {\n this.logger = logger;\n this.configValidator = new PluginConfigValidator(logger);\n }\n\n /**\n * Set the plugin context for service factories\n */\n setContext(context: PluginContext): void {\n this.context = context;\n }\n\n /**\n * Get a synchronous service instance if it exists (Sync Helper)\n */\n getServiceInstance<T>(name: string): T | undefined {\n return this.serviceInstances.get(name) as T;\n }\n\n /**\n * Load a plugin asynchronously with validation\n */\n async loadPlugin(plugin: Plugin): Promise<PluginLoadResult> {\n const startTime = Date.now();\n \n try {\n this.logger.info(`Loading plugin: ${plugin.name}`);\n \n // Convert to PluginMetadata\n const metadata = this.toPluginMetadata(plugin);\n \n // Validate plugin structure\n this.validatePluginStructure(metadata);\n \n // Check version compatibility\n const versionCheck = this.checkVersionCompatibility(metadata);\n if (!versionCheck.compatible) {\n throw new Error(`Version incompatible: ${versionCheck.message}`);\n }\n \n // Validate configuration if schema is provided\n if (metadata.configSchema) {\n this.validatePluginConfig(metadata);\n }\n \n // Verify signature if provided\n if (metadata.signature) {\n await this.verifyPluginSignature(metadata);\n }\n \n // Store loaded plugin\n this.loadedPlugins.set(metadata.name, metadata);\n \n const loadTime = Date.now() - startTime;\n this.logger.info(`Plugin loaded: ${plugin.name} (${loadTime}ms)`);\n \n return {\n success: true,\n plugin: metadata,\n loadTime,\n };\n } catch (error) {\n this.logger.error(`Failed to load plugin: ${plugin.name}`, error as Error);\n return {\n success: false,\n error: error as Error,\n loadTime: Date.now() - startTime,\n };\n }\n }\n\n /**\n * Register a service with factory function\n */\n registerServiceFactory(registration: ServiceRegistration): void {\n if (this.serviceFactories.has(registration.name)) {\n throw new Error(`Service factory '${registration.name}' already registered`);\n }\n \n this.serviceFactories.set(registration.name, registration);\n this.logger.debug(`Service factory registered: ${registration.name} (${registration.lifecycle})`);\n }\n\n /**\n * Get or create a service instance based on lifecycle type\n */\n async getService<T>(name: string, scopeId?: string): Promise<T> {\n const registration = this.serviceFactories.get(name);\n \n if (!registration) {\n // Fall back to static service instances\n const instance = this.serviceInstances.get(name);\n if (!instance) {\n throw new Error(`Service '${name}' not found`);\n }\n return instance as T;\n }\n \n switch (registration.lifecycle) {\n case ServiceLifecycle.SINGLETON:\n return await this.getSingletonService<T>(registration);\n \n case ServiceLifecycle.TRANSIENT:\n return await this.createTransientService<T>(registration);\n \n case ServiceLifecycle.SCOPED:\n if (!scopeId) {\n throw new Error(`Scope ID required for scoped service '${name}'`);\n }\n return await this.getScopedService<T>(registration, scopeId);\n \n default:\n throw new Error(`Unknown service lifecycle: ${registration.lifecycle}`);\n }\n }\n\n /**\n * Register a static service instance (legacy support)\n */\n registerService(name: string, service: any): void {\n if (this.serviceInstances.has(name)) {\n throw new Error(`Service '${name}' already registered`);\n }\n this.serviceInstances.set(name, service);\n }\n\n /**\n * Check if a service is registered (either as instance or factory)\n */\n hasService(name: string): boolean {\n return this.serviceInstances.has(name) || this.serviceFactories.has(name);\n }\n\n /**\n * Detect circular dependencies in service factories\n * Note: This only detects cycles in service dependencies, not plugin dependencies.\n * Plugin dependency cycles are detected in the kernel's resolveDependencies method.\n */\n detectCircularDependencies(): string[] {\n const cycles: string[] = [];\n const visited = new Set<string>();\n const visiting = new Set<string>();\n \n const visit = (serviceName: string, path: string[] = []) => {\n if (visiting.has(serviceName)) {\n const cycle = [...path, serviceName].join(' -> ');\n cycles.push(cycle);\n return;\n }\n \n if (visited.has(serviceName)) {\n return;\n }\n \n visiting.add(serviceName);\n \n const registration = this.serviceFactories.get(serviceName);\n if (registration?.dependencies) {\n for (const dep of registration.dependencies) {\n visit(dep, [...path, serviceName]);\n }\n }\n \n visiting.delete(serviceName);\n visited.add(serviceName);\n };\n \n for (const serviceName of this.serviceFactories.keys()) {\n visit(serviceName);\n }\n \n return cycles;\n }\n\n /**\n * Check plugin health\n */\n async checkPluginHealth(pluginName: string): Promise<PluginHealthStatus> {\n const plugin = this.loadedPlugins.get(pluginName);\n \n if (!plugin) {\n return {\n healthy: false,\n message: 'Plugin not found',\n lastCheck: new Date(),\n };\n }\n \n if (!plugin.healthCheck) {\n return {\n healthy: true,\n message: 'No health check defined',\n lastCheck: new Date(),\n };\n }\n \n try {\n const status = await plugin.healthCheck();\n return {\n ...status,\n lastCheck: new Date(),\n };\n } catch (error) {\n return {\n healthy: false,\n message: `Health check failed: ${(error as Error).message}`,\n lastCheck: new Date(),\n };\n }\n }\n\n /**\n * Clear scoped services for a scope\n */\n clearScope(scopeId: string): void {\n this.scopedServices.delete(scopeId);\n this.logger.debug(`Cleared scope: ${scopeId}`);\n }\n\n /**\n * Get all loaded plugins\n */\n getLoadedPlugins(): Map<string, PluginMetadata> {\n return new Map(this.loadedPlugins);\n }\n\n // Private helper methods\n\n private toPluginMetadata(plugin: Plugin): PluginMetadata {\n // Fix: Do not use object spread {...plugin} as it destroys the prototype chain for Class-based plugins.\n // Instead, cast the original object and inject default values if missing.\n const metadata = plugin as PluginMetadata;\n \n if (!metadata.version) {\n metadata.version = '0.0.0';\n }\n \n return metadata;\n }\n\n private validatePluginStructure(plugin: PluginMetadata): void {\n if (!plugin.name) {\n throw new Error('Plugin name is required');\n }\n \n if (!plugin.init) {\n throw new Error('Plugin init function is required');\n }\n \n if (!this.isValidSemanticVersion(plugin.version)) {\n throw new Error(`Invalid semantic version: ${plugin.version}`);\n }\n }\n\n private checkVersionCompatibility(plugin: PluginMetadata): VersionCompatibility {\n // Basic semantic version compatibility check\n // In a real implementation, this would check against kernel version\n const version = plugin.version;\n \n if (!this.isValidSemanticVersion(version)) {\n return {\n compatible: false,\n pluginVersion: version,\n message: 'Invalid semantic version format',\n };\n }\n \n return {\n compatible: true,\n pluginVersion: version,\n };\n }\n\n private isValidSemanticVersion(version: string): boolean {\n const semverRegex = /^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?(\\+[a-zA-Z0-9.-]+)?$/;\n return semverRegex.test(version);\n }\n\n private validatePluginConfig(plugin: PluginMetadata, config?: any): void {\n if (!plugin.configSchema) {\n return;\n }\n\n if (config === undefined) {\n // In loadPlugin, we often don't have the config yet.\n // We skip validation here or valid against empty object if schema allows?\n // For now, let's keep the logging behavior but note it's delegating\n this.logger.debug(`Plugin ${plugin.name} has configuration schema (config validation postponed)`);\n return;\n }\n\n this.configValidator.validatePluginConfig(plugin, config);\n }\n\n private async verifyPluginSignature(plugin: PluginMetadata): Promise<void> {\n if (!plugin.signature) {\n return;\n }\n \n // Plugin signature verification is now implemented in PluginSignatureVerifier\n // This is a placeholder that logs the verification would happen\n // The actual verification should be done by the caller with proper security config\n this.logger.debug(`Plugin ${plugin.name} has signature (use PluginSignatureVerifier for verification)`);\n }\n\n private async getSingletonService<T>(registration: ServiceRegistration): Promise<T> {\n let instance = this.serviceInstances.get(registration.name);\n \n if (!instance) {\n // Create instance (would need context)\n instance = await this.createServiceInstance(registration);\n this.serviceInstances.set(registration.name, instance);\n this.logger.debug(`Singleton service created: ${registration.name}`);\n }\n \n return instance as T;\n }\n\n private async createTransientService<T>(registration: ServiceRegistration): Promise<T> {\n const instance = await this.createServiceInstance(registration);\n this.logger.debug(`Transient service created: ${registration.name}`);\n return instance as T;\n }\n\n private async getScopedService<T>(registration: ServiceRegistration, scopeId: string): Promise<T> {\n if (!this.scopedServices.has(scopeId)) {\n this.scopedServices.set(scopeId, new Map());\n }\n \n const scope = this.scopedServices.get(scopeId)!;\n let instance = scope.get(registration.name);\n \n if (!instance) {\n instance = await this.createServiceInstance(registration);\n scope.set(registration.name, instance);\n this.logger.debug(`Scoped service created: ${registration.name} (scope: ${scopeId})`);\n }\n \n return instance as T;\n }\n\n private async createServiceInstance(registration: ServiceRegistration): Promise<any> {\n if (!this.context) {\n throw new Error(`[PluginLoader] Context not set - cannot create service '${registration.name}'`);\n }\n\n if (this.creating.has(registration.name)) {\n throw new Error(`Circular dependency detected: ${Array.from(this.creating).join(' -> ')} -> ${registration.name}`);\n }\n\n this.creating.add(registration.name);\n try {\n return await registration.factory(this.context);\n } finally {\n this.creating.delete(registration.name);\n }\n }\n}\n","import { Plugin } from './types.js';\nimport { createLogger, ObjectLogger } from './logger.js';\nimport type { LoggerConfig } from '@objectstack/spec/system';\nimport { ObjectKernelBase } from './kernel-base.js';\n\n/**\n * ObjectKernel - MiniKernel Architecture\n * \n * A highly modular, plugin-based microkernel that:\n * - Manages plugin lifecycle (init, start, destroy)\n * - Provides dependency injection via service registry\n * - Implements event/hook system for inter-plugin communication\n * - Handles dependency resolution (topological sort)\n * - Provides configurable logging for server and browser\n * \n * Core philosophy:\n * - Business logic is completely separated into plugins\n * - Kernel only manages lifecycle, DI, and hooks\n * - Plugins are loaded as equal building blocks\n */\nexport class LiteKernel extends ObjectKernelBase {\n constructor(config?: { logger?: Partial<LoggerConfig> }) {\n const logger = createLogger(config?.logger);\n super(logger);\n \n // Initialize context after logger is created\n this.context = this.createContext();\n }\n\n /**\n * Register a plugin\n * @param plugin - Plugin instance\n */\n use(plugin: Plugin): this {\n this.validateIdle();\n\n const pluginName = plugin.name;\n if (this.plugins.has(pluginName)) {\n throw new Error(`[Kernel] Plugin '${pluginName}' already registered`);\n }\n\n this.plugins.set(pluginName, plugin);\n return this;\n }\n\n /**\n * Bootstrap the kernel\n * 1. Resolve dependencies (topological sort)\n * 2. Init phase - plugins register services\n * 3. Start phase - plugins execute business logic\n * 4. Trigger 'kernel:ready' hook\n */\n async bootstrap(): Promise<void> {\n this.validateState('idle');\n\n this.state = 'initializing';\n this.logger.info('Bootstrap started');\n\n // Resolve dependencies\n const orderedPlugins = this.resolveDependencies();\n\n // Phase 1: Init - Plugins register services\n this.logger.info('Phase 1: Init plugins');\n for (const plugin of orderedPlugins) {\n await this.runPluginInit(plugin);\n }\n\n // Phase 2: Start - Plugins execute business logic\n this.logger.info('Phase 2: Start plugins');\n this.state = 'running';\n \n for (const plugin of orderedPlugins) {\n await this.runPluginStart(plugin);\n }\n\n // Trigger ready hook\n await this.triggerHook('kernel:ready');\n this.logger.info('✅ Bootstrap complete', { \n pluginCount: this.plugins.size \n });\n }\n\n /**\n * Shutdown the kernel\n * Calls destroy on all plugins in reverse order\n */\n async shutdown(): Promise<void> {\n await this.destroy();\n }\n\n /**\n * Graceful shutdown - destroy all plugins in reverse order\n */\n async destroy(): Promise<void> {\n if (this.state === 'stopped') {\n this.logger.warn('Kernel already stopped');\n return;\n }\n\n this.state = 'stopping';\n this.logger.info('Shutdown started');\n\n // Trigger shutdown hook\n await this.triggerHook('kernel:shutdown');\n\n // Destroy plugins in reverse order\n const orderedPlugins = this.resolveDependencies();\n for (const plugin of orderedPlugins.reverse()) {\n await this.runPluginDestroy(plugin);\n }\n\n this.state = 'stopped';\n this.logger.info('✅ Shutdown complete');\n \n // Cleanup logger resources\n if (this.logger && typeof (this.logger as ObjectLogger).destroy === 'function') {\n await (this.logger as ObjectLogger).destroy();\n }\n }\n\n /**\n * Get a service from the registry\n * Convenience method for external access\n */\n getService<T>(name: string): T {\n return this.context.getService<T>(name);\n }\n\n /**\n * Check if kernel is running\n */\n isRunning(): boolean {\n return this.state === 'running';\n }\n}\n","import type {\n ApiRegistry as ApiRegistryType,\n ApiRegistryEntry,\n ApiRegistryEntryInput,\n ApiEndpointRegistration,\n ConflictResolutionStrategy,\n ApiDiscoveryQuery,\n ApiDiscoveryResponse,\n} from '@objectstack/spec/api';\nimport { ApiRegistryEntrySchema } from '@objectstack/spec/api';\nimport type { Logger } from '@objectstack/spec/contracts';\nimport { getEnv } from './utils/env.js';\n\n/**\n * API Registry Service\n * \n * Central registry for managing API endpoints across different protocols.\n * Provides endpoint registration, discovery, and conflict resolution.\n * \n * **Features:**\n * - Multi-protocol support (REST, GraphQL, OData, WebSocket, etc.)\n * - Route conflict detection with configurable resolution strategies\n * - RBAC permission integration\n * - Dynamic schema linking with ObjectQL references\n * - Plugin API registration\n * \n * **Architecture Alignment:**\n * - Kubernetes: Service Discovery & API Server\n * - AWS API Gateway: Unified API Management\n * - Kong Gateway: Plugin-based API Management\n * \n * @example\n * ```typescript\n * const registry = new ApiRegistry(logger, 'priority');\n * \n * // Register an API\n * registry.registerApi({\n * id: 'customer_api',\n * name: 'Customer API',\n * type: 'rest',\n * version: 'v1',\n * basePath: '/api/v1/customers',\n * endpoints: [...]\n * });\n * \n * // Discover APIs\n * const apis = registry.findApis({ type: 'rest', status: 'active' });\n * \n * // Get registry snapshot\n * const snapshot = registry.getRegistry();\n * ```\n */\nexport class ApiRegistry {\n private apis: Map<string, ApiRegistryEntry> = new Map();\n private endpoints: Map<string, { api: string; endpoint: ApiEndpointRegistration }> = new Map();\n private routes: Map<string, { api: string; endpointId: string; priority: number }> = new Map();\n \n // Performance optimization: Auxiliary indices for O(1) lookups\n private apisByType: Map<string, Set<string>> = new Map();\n private apisByTag: Map<string, Set<string>> = new Map();\n private apisByStatus: Map<string, Set<string>> = new Map();\n \n private conflictResolution: ConflictResolutionStrategy;\n private logger: Logger;\n private version: string;\n private updatedAt: string;\n\n constructor(\n logger: Logger,\n conflictResolution: ConflictResolutionStrategy = 'error',\n version: string = '1.0.0'\n ) {\n this.logger = logger;\n this.conflictResolution = conflictResolution;\n this.version = version;\n this.updatedAt = new Date().toISOString();\n }\n\n /**\n * Register an API with its endpoints\n * \n * @param api - API registry entry\n * @throws Error if API already registered or route conflicts detected\n */\n registerApi(api: ApiRegistryEntryInput): void {\n // Check if API already exists\n if (this.apis.has(api.id)) {\n throw new Error(`[ApiRegistry] API '${api.id}' already registered`);\n }\n\n // Parse and validate the input using Zod schema\n const fullApi = ApiRegistryEntrySchema.parse(api);\n\n // Validate and register endpoints\n for (const endpoint of fullApi.endpoints) {\n this.validateEndpoint(endpoint, fullApi.id);\n }\n\n // Register the API\n this.apis.set(fullApi.id, fullApi);\n \n // Register endpoints\n for (const endpoint of fullApi.endpoints) {\n this.registerEndpoint(fullApi.id, endpoint);\n }\n\n // Update auxiliary indices for performance optimization\n this.updateIndices(fullApi);\n\n this.updatedAt = new Date().toISOString();\n this.logger.info(`API registered: ${fullApi.id}`, {\n api: fullApi.id,\n type: fullApi.type,\n endpointCount: fullApi.endpoints.length,\n });\n }\n\n /**\n * Unregister an API and all its endpoints\n * \n * @param apiId - API identifier\n */\n unregisterApi(apiId: string): void {\n const api = this.apis.get(apiId);\n if (!api) {\n throw new Error(`[ApiRegistry] API '${apiId}' not found`);\n }\n\n // Remove all endpoints\n for (const endpoint of api.endpoints) {\n this.unregisterEndpoint(apiId, endpoint.id);\n }\n\n // Remove from auxiliary indices\n this.removeFromIndices(api);\n\n // Remove the API\n this.apis.delete(apiId);\n this.updatedAt = new Date().toISOString();\n \n this.logger.info(`API unregistered: ${apiId}`);\n }\n\n /**\n * Register a single endpoint\n * \n * @param apiId - API identifier\n * @param endpoint - Endpoint registration\n * @throws Error if route conflict detected\n */\n private registerEndpoint(apiId: string, endpoint: ApiEndpointRegistration): void {\n const endpointKey = `${apiId}:${endpoint.id}`;\n \n // Check if endpoint already registered\n if (this.endpoints.has(endpointKey)) {\n throw new Error(`[ApiRegistry] Endpoint '${endpoint.id}' already registered for API '${apiId}'`);\n }\n\n // Register endpoint\n this.endpoints.set(endpointKey, { api: apiId, endpoint });\n\n // Register route if path is defined\n if (endpoint.path) {\n this.registerRoute(apiId, endpoint);\n }\n }\n\n /**\n * Unregister a single endpoint\n * \n * @param apiId - API identifier\n * @param endpointId - Endpoint identifier\n */\n private unregisterEndpoint(apiId: string, endpointId: string): void {\n const endpointKey = `${apiId}:${endpointId}`;\n const entry = this.endpoints.get(endpointKey);\n \n if (!entry) {\n return; // Already unregistered\n }\n\n // Unregister route\n if (entry.endpoint.path) {\n const routeKey = this.getRouteKey(entry.endpoint);\n this.routes.delete(routeKey);\n }\n\n // Unregister endpoint\n this.endpoints.delete(endpointKey);\n }\n\n /**\n * Register a route with conflict detection\n * \n * @param apiId - API identifier\n * @param endpoint - Endpoint registration\n * @throws Error if route conflict detected (based on strategy)\n */\n private registerRoute(apiId: string, endpoint: ApiEndpointRegistration): void {\n const routeKey = this.getRouteKey(endpoint);\n const priority = endpoint.priority ?? 100;\n const existingRoute = this.routes.get(routeKey);\n\n if (existingRoute) {\n // Route conflict detected\n this.handleRouteConflict(routeKey, apiId, endpoint, existingRoute, priority);\n return;\n }\n\n // Register route\n this.routes.set(routeKey, {\n api: apiId,\n endpointId: endpoint.id,\n priority,\n });\n }\n\n /**\n * Handle route conflict based on resolution strategy\n * \n * @param routeKey - Route key\n * @param apiId - New API identifier\n * @param endpoint - New endpoint\n * @param existingRoute - Existing route registration\n * @param newPriority - New endpoint priority\n * @throws Error if strategy is 'error'\n */\n private handleRouteConflict(\n routeKey: string,\n apiId: string,\n endpoint: ApiEndpointRegistration,\n existingRoute: { api: string; endpointId: string; priority: number },\n newPriority: number\n ): void {\n const strategy = this.conflictResolution;\n\n switch (strategy) {\n case 'error':\n throw new Error(\n `[ApiRegistry] Route conflict detected: '${routeKey}' is already registered by API '${existingRoute.api}' endpoint '${existingRoute.endpointId}'`\n );\n\n case 'priority':\n if (newPriority > existingRoute.priority) {\n // New endpoint has higher priority, replace\n this.logger.warn(\n `Route conflict: replacing '${routeKey}' (priority ${existingRoute.priority} -> ${newPriority})`,\n {\n oldApi: existingRoute.api,\n oldEndpoint: existingRoute.endpointId,\n newApi: apiId,\n newEndpoint: endpoint.id,\n }\n );\n this.routes.set(routeKey, {\n api: apiId,\n endpointId: endpoint.id,\n priority: newPriority,\n });\n } else {\n // Existing endpoint has higher priority, keep it\n this.logger.warn(\n `Route conflict: keeping existing '${routeKey}' (priority ${existingRoute.priority} >= ${newPriority})`,\n {\n existingApi: existingRoute.api,\n existingEndpoint: existingRoute.endpointId,\n newApi: apiId,\n newEndpoint: endpoint.id,\n }\n );\n }\n break;\n\n case 'first-wins':\n // Keep existing route\n this.logger.warn(\n `Route conflict: keeping first registered '${routeKey}'`,\n {\n existingApi: existingRoute.api,\n newApi: apiId,\n }\n );\n break;\n\n case 'last-wins':\n // Replace with new route\n this.logger.warn(\n `Route conflict: replacing with last registered '${routeKey}'`,\n {\n oldApi: existingRoute.api,\n newApi: apiId,\n }\n );\n this.routes.set(routeKey, {\n api: apiId,\n endpointId: endpoint.id,\n priority: newPriority,\n });\n break;\n\n default:\n throw new Error(`[ApiRegistry] Unknown conflict resolution strategy: ${strategy}`);\n }\n }\n\n /**\n * Generate a unique route key for conflict detection\n * \n * NOTE: This implementation uses exact string matching for route conflict detection.\n * It works well for static paths but has limitations with parameterized routes.\n * For example, `/api/users/:id` and `/api/users/:userId` will NOT be detected as conflicts\n * even though they are semantically identical parameterized patterns. Similarly,\n * `/api/:resource/list` and `/api/:entity/list` would also not be detected as conflicting.\n * \n * For more advanced conflict detection (e.g., path-to-regexp pattern matching),\n * consider integrating with your routing library's conflict detection mechanism.\n * \n * @param endpoint - Endpoint registration\n * @returns Route key (e.g., \"GET:/api/v1/customers/:id\")\n */\n private getRouteKey(endpoint: ApiEndpointRegistration): string {\n const method = endpoint.method || 'ANY';\n return `${method}:${endpoint.path}`;\n }\n\n /**\n * Validate endpoint registration\n * \n * @param endpoint - Endpoint to validate\n * @param apiId - API identifier (for error messages)\n * @throws Error if endpoint is invalid\n */\n private validateEndpoint(endpoint: ApiEndpointRegistration, apiId: string): void {\n if (!endpoint.id) {\n throw new Error(`[ApiRegistry] Endpoint in API '${apiId}' missing 'id' field`);\n }\n\n if (!endpoint.path) {\n throw new Error(`[ApiRegistry] Endpoint '${endpoint.id}' in API '${apiId}' missing 'path' field`);\n }\n }\n\n /**\n * Get an API by ID\n * \n * @param apiId - API identifier\n * @returns API registry entry or undefined\n */\n getApi(apiId: string): ApiRegistryEntry | undefined {\n return this.apis.get(apiId);\n }\n\n /**\n * Get all registered APIs\n * \n * @returns Array of all APIs\n */\n getAllApis(): ApiRegistryEntry[] {\n return Array.from(this.apis.values());\n }\n\n /**\n * Find APIs matching query criteria\n * \n * Performance optimized with auxiliary indices for O(1) lookups on type, tags, and status.\n * \n * @param query - Discovery query parameters\n * @returns Matching APIs\n */\n findApis(query: ApiDiscoveryQuery): ApiDiscoveryResponse {\n let resultIds: Set<string> | undefined;\n\n // Use indices for performance-optimized filtering\n // Start with the most restrictive filter to minimize subsequent filtering\n \n // Filter by type (using index for O(1) lookup)\n if (query.type) {\n const typeIds = this.apisByType.get(query.type);\n if (!typeIds || typeIds.size === 0) {\n return { apis: [], total: 0, filters: query };\n }\n resultIds = new Set(typeIds);\n }\n\n // Filter by status (using index for O(1) lookup)\n if (query.status) {\n const statusIds = this.apisByStatus.get(query.status);\n if (!statusIds || statusIds.size === 0) {\n return { apis: [], total: 0, filters: query };\n }\n \n if (resultIds) {\n // Intersect with previous results\n resultIds = new Set([...resultIds].filter(id => statusIds.has(id)));\n } else {\n resultIds = new Set(statusIds);\n }\n \n if (resultIds.size === 0) {\n return { apis: [], total: 0, filters: query };\n }\n }\n\n // Filter by tags (using index for O(M) lookup where M is number of tags)\n if (query.tags && query.tags.length > 0) {\n const tagMatches = new Set<string>();\n \n for (const tag of query.tags) {\n const tagIds = this.apisByTag.get(tag);\n if (tagIds) {\n tagIds.forEach(id => tagMatches.add(id));\n }\n }\n \n if (tagMatches.size === 0) {\n return { apis: [], total: 0, filters: query };\n }\n \n if (resultIds) {\n // Intersect with previous results\n resultIds = new Set([...resultIds].filter(id => tagMatches.has(id)));\n } else {\n resultIds = tagMatches;\n }\n \n if (resultIds.size === 0) {\n return { apis: [], total: 0, filters: query };\n }\n }\n\n // Get the actual API objects\n let results: ApiRegistryEntry[];\n if (resultIds) {\n results = Array.from(resultIds)\n .map(id => this.apis.get(id))\n .filter((api): api is ApiRegistryEntry => api !== undefined);\n } else {\n results = Array.from(this.apis.values());\n }\n\n // Apply remaining filters that don't have indices (less common filters)\n \n // Filter by plugin source\n if (query.pluginSource) {\n results = results.filter(\n (api) => api.metadata?.pluginSource === query.pluginSource\n );\n }\n\n // Filter by version\n if (query.version) {\n results = results.filter((api) => api.version === query.version);\n }\n\n // Search in name/description\n if (query.search) {\n const searchLower = query.search.toLowerCase();\n results = results.filter(\n (api) =>\n api.name.toLowerCase().includes(searchLower) ||\n (api.description && api.description.toLowerCase().includes(searchLower))\n );\n }\n\n return {\n apis: results,\n total: results.length,\n filters: query,\n };\n }\n\n /**\n * Get endpoint by API ID and endpoint ID\n * \n * @param apiId - API identifier\n * @param endpointId - Endpoint identifier\n * @returns Endpoint registration or undefined\n */\n getEndpoint(apiId: string, endpointId: string): ApiEndpointRegistration | undefined {\n const key = `${apiId}:${endpointId}`;\n return this.endpoints.get(key)?.endpoint;\n }\n\n /**\n * Find endpoint by route (method + path)\n * \n * @param method - HTTP method\n * @param path - URL path\n * @returns Endpoint registration or undefined\n */\n findEndpointByRoute(method: string, path: string): {\n api: ApiRegistryEntry;\n endpoint: ApiEndpointRegistration;\n } | undefined {\n const routeKey = `${method}:${path}`;\n const route = this.routes.get(routeKey);\n \n if (!route) {\n return undefined;\n }\n\n const api = this.apis.get(route.api);\n const endpoint = this.getEndpoint(route.api, route.endpointId);\n\n if (!api || !endpoint) {\n return undefined;\n }\n\n return { api, endpoint };\n }\n\n /**\n * Get complete registry snapshot\n * \n * @returns Current registry state\n */\n getRegistry(): ApiRegistryType {\n const apis = Array.from(this.apis.values());\n \n // Group by type\n const byType: Record<string, ApiRegistryEntry[]> = {};\n for (const api of apis) {\n if (!byType[api.type]) {\n byType[api.type] = [];\n }\n byType[api.type].push(api);\n }\n\n // Group by status\n const byStatus: Record<string, ApiRegistryEntry[]> = {};\n for (const api of apis) {\n const status = api.metadata?.status || 'active';\n if (!byStatus[status]) {\n byStatus[status] = [];\n }\n byStatus[status].push(api);\n }\n\n // Count total endpoints\n const totalEndpoints = apis.reduce(\n (sum, api) => sum + api.endpoints.length,\n 0\n );\n\n return {\n version: this.version,\n conflictResolution: this.conflictResolution,\n apis,\n totalApis: apis.length,\n totalEndpoints,\n byType,\n byStatus,\n updatedAt: this.updatedAt,\n };\n }\n\n /**\n * Clear all registered APIs\n * \n * **⚠️ SAFETY WARNING:**\n * This method clears all registered APIs and should be used with caution.\n * \n * **Usage Restrictions:**\n * - In production environments (NODE_ENV=production), a `force: true` parameter is required\n * - Primarily intended for testing and development hot-reload scenarios\n * \n * @param options - Clear options\n * @param options.force - Force clear in production environment (default: false)\n * @throws Error if called in production without force flag\n * \n * @example Safe usage in tests\n * ```typescript\n * beforeEach(() => {\n * registry.clear(); // OK in test environment\n * });\n * ```\n * \n * @example Usage in production (requires explicit force)\n * ```typescript\n * // In production, explicit force is required\n * registry.clear({ force: true });\n * ```\n */\n clear(options: { force?: boolean } = {}): void {\n const isProduction = this.isProductionEnvironment();\n \n if (isProduction && !options.force) {\n throw new Error(\n '[ApiRegistry] Cannot clear registry in production environment without force flag. ' +\n 'Use clear({ force: true }) if you really want to clear the registry.'\n );\n }\n\n this.apis.clear();\n this.endpoints.clear();\n this.routes.clear();\n \n // Clear auxiliary indices\n this.apisByType.clear();\n this.apisByTag.clear();\n this.apisByStatus.clear();\n \n this.updatedAt = new Date().toISOString();\n \n if (isProduction) {\n this.logger.warn('API registry forcefully cleared in production', { force: options.force });\n } else {\n this.logger.info('API registry cleared');\n }\n }\n\n /**\n * Get registry statistics\n * \n * @returns Registry statistics\n */\n getStats(): {\n totalApis: number;\n totalEndpoints: number;\n totalRoutes: number;\n apisByType: Record<string, number>;\n endpointsByApi: Record<string, number>;\n } {\n const apis = Array.from(this.apis.values());\n \n const apisByType: Record<string, number> = {};\n for (const api of apis) {\n apisByType[api.type] = (apisByType[api.type] || 0) + 1;\n }\n\n const endpointsByApi: Record<string, number> = {};\n for (const api of apis) {\n endpointsByApi[api.id] = api.endpoints.length;\n }\n\n return {\n totalApis: this.apis.size,\n totalEndpoints: this.endpoints.size,\n totalRoutes: this.routes.size,\n apisByType,\n endpointsByApi,\n };\n }\n\n /**\n * Update auxiliary indices when an API is registered\n * \n * @param api - API entry to index\n * @private\n * @internal\n */\n private updateIndices(api: ApiRegistryEntry): void {\n // Index by type\n this.ensureIndexSet(this.apisByType, api.type).add(api.id);\n\n // Index by status\n const status = api.metadata?.status || 'active';\n this.ensureIndexSet(this.apisByStatus, status).add(api.id);\n\n // Index by tags\n const tags = api.metadata?.tags || [];\n for (const tag of tags) {\n this.ensureIndexSet(this.apisByTag, tag).add(api.id);\n }\n }\n\n /**\n * Remove API from auxiliary indices when unregistered\n * \n * @param api - API entry to remove from indices\n * @private\n * @internal\n */\n private removeFromIndices(api: ApiRegistryEntry): void {\n // Remove from type index\n this.removeFromIndexSet(this.apisByType, api.type, api.id);\n\n // Remove from status index\n const status = api.metadata?.status || 'active';\n this.removeFromIndexSet(this.apisByStatus, status, api.id);\n\n // Remove from tag indices\n const tags = api.metadata?.tags || [];\n for (const tag of tags) {\n this.removeFromIndexSet(this.apisByTag, tag, api.id);\n }\n }\n\n /**\n * Helper to ensure an index set exists and return it\n * \n * @param map - Index map\n * @param key - Index key\n * @returns The Set for this key (created if needed)\n * @private\n * @internal\n */\n private ensureIndexSet(map: Map<string, Set<string>>, key: string): Set<string> {\n let set = map.get(key);\n if (!set) {\n set = new Set();\n map.set(key, set);\n }\n return set;\n }\n\n /**\n * Helper to remove an ID from an index set and clean up empty sets\n * \n * @param map - Index map\n * @param key - Index key\n * @param id - API ID to remove\n * @private\n * @internal\n */\n private removeFromIndexSet(map: Map<string, Set<string>>, key: string, id: string): void {\n const set = map.get(key);\n if (set) {\n set.delete(id);\n // Clean up empty sets to avoid memory leaks\n if (set.size === 0) {\n map.delete(key);\n }\n }\n }\n\n /**\n * Check if running in production environment\n * \n * @returns true if NODE_ENV is 'production'\n * @private\n * @internal\n */\n private isProductionEnvironment(): boolean {\n return getEnv('NODE_ENV') === 'production';\n }\n}\n","import type { Plugin, PluginContext } from './types.js';\nimport { ApiRegistry } from './api-registry.js';\nimport type { ConflictResolutionStrategy } from '@objectstack/spec/api';\n\n/**\n * API Registry Plugin Configuration\n */\nexport interface ApiRegistryPluginConfig {\n /**\n * Conflict resolution strategy for route conflicts\n * @default 'error'\n */\n conflictResolution?: ConflictResolutionStrategy;\n \n /**\n * Registry version\n * @default '1.0.0'\n */\n version?: string;\n}\n\n/**\n * API Registry Plugin\n * \n * Registers the API Registry service in the kernel, making it available\n * to all plugins for endpoint registration and discovery.\n * \n * **Usage:**\n * ```typescript\n * const kernel = new ObjectKernel();\n * \n * // Register API Registry Plugin\n * kernel.use(createApiRegistryPlugin({ conflictResolution: 'priority' }));\n * \n * // In other plugins, access the API Registry\n * const plugin: Plugin = {\n * name: 'my-plugin',\n * init: async (ctx) => {\n * const registry = ctx.getService<ApiRegistry>('api-registry');\n * \n * // Register plugin APIs\n * registry.registerApi({\n * id: 'my_plugin_api',\n * name: 'My Plugin API',\n * type: 'rest',\n * version: 'v1',\n * basePath: '/api/v1/my-plugin',\n * endpoints: [...]\n * });\n * }\n * };\n * ```\n * \n * @param config - Plugin configuration\n * @returns Plugin instance\n */\nexport function createApiRegistryPlugin(\n config: ApiRegistryPluginConfig = {}\n): Plugin {\n const {\n conflictResolution = 'error',\n version = '1.0.0',\n } = config;\n\n return {\n name: 'com.objectstack.core.api-registry',\n type: 'standard',\n version: '1.0.0',\n\n init: async (ctx: PluginContext) => {\n // Create API Registry instance\n const registry = new ApiRegistry(\n ctx.logger,\n conflictResolution,\n version\n );\n\n // Register as a service\n ctx.registerService('api-registry', registry);\n\n ctx.logger.info('API Registry plugin initialized', {\n conflictResolution,\n version,\n });\n },\n };\n}\n","export * from './adapter.js';\nexport * from './runner.js';\nexport * from './http-adapter.js';\n","import { QA } from '@objectstack/spec';\nimport { TestExecutionAdapter } from './adapter.js';\n\nexport interface TestResult {\n scenarioId: string;\n passed: boolean;\n steps: StepResult[];\n error?: unknown;\n duration: number;\n}\n\nexport interface StepResult {\n stepName: string;\n passed: boolean;\n error?: unknown;\n output?: unknown;\n duration: number;\n}\n\nexport class TestRunner {\n constructor(private adapter: TestExecutionAdapter) {}\n\n async runSuite(suite: QA.TestSuite): Promise<TestResult[]> {\n const results: TestResult[] = [];\n for (const scenario of suite.scenarios) {\n results.push(await this.runScenario(scenario));\n }\n return results;\n }\n\n async runScenario(scenario: QA.TestScenario): Promise<TestResult> {\n const startTime = Date.now();\n const context: Record<string, unknown> = {}; // Variable context\n \n // Initialize context from initial payload if needed? Currently schema doesn't have initial context prop on Scenario\n // But we defined TestContextSchema separately.\n \n // Setup\n if (scenario.setup) {\n for (const step of scenario.setup) {\n try {\n await this.runStep(step, context);\n } catch (e) {\n return {\n scenarioId: scenario.id,\n passed: false,\n steps: [],\n error: `Setup failed: ${e instanceof Error ? e.message : String(e)}`,\n duration: Date.now() - startTime\n };\n }\n }\n }\n\n const stepResults: StepResult[] = [];\n let scenarioPassed = true;\n let scenarioError: unknown = undefined;\n\n // Main Steps\n for (const step of scenario.steps) {\n const stepStartTime = Date.now();\n try {\n const output = await this.runStep(step, context);\n stepResults.push({\n stepName: step.name,\n passed: true,\n output,\n duration: Date.now() - stepStartTime\n });\n } catch (e) {\n scenarioPassed = false;\n scenarioError = e;\n stepResults.push({\n stepName: step.name,\n passed: false,\n error: e,\n duration: Date.now() - stepStartTime\n });\n break; // Stop on first failure\n }\n }\n\n // Teardown (run even if failed)\n if (scenario.teardown) {\n for (const step of scenario.teardown) {\n try {\n await this.runStep(step, context);\n } catch (e) {\n // Log teardown failure but don't override main failure if it exists\n if (scenarioPassed) {\n scenarioPassed = false;\n scenarioError = `Teardown failed: ${e instanceof Error ? e.message : String(e)}`;\n }\n }\n }\n }\n\n return {\n scenarioId: scenario.id,\n passed: scenarioPassed,\n steps: stepResults,\n error: scenarioError,\n duration: Date.now() - startTime\n };\n }\n\n private async runStep(step: QA.TestStep, context: Record<string, unknown>): Promise<unknown> {\n // 1. Resolve Variables with Context (Simple interpolation or just pass context?)\n // For now, assume adpater handles context resolution or we do basic replacement\n const resolvedAction = this.resolveVariables(step.action, context);\n\n // 2. Execute Action\n const result = await this.adapter.execute(resolvedAction, context);\n\n // 3. Capture Outputs\n if (step.capture) {\n for (const [varName, path] of Object.entries(step.capture)) {\n context[varName] = this.getValueByPath(result, path);\n }\n }\n\n // 4. Run Assertions\n if (step.assertions) {\n for (const assertion of step.assertions) {\n this.assert(result, assertion, context);\n }\n }\n\n return result;\n }\n\n private resolveVariables(action: QA.TestAction, _context: Record<string, unknown>): QA.TestAction {\n // TODO: Implement JSON path variable substitution stringify/parse\n // For now returning as is\n return action; \n }\n\n private getValueByPath(obj: unknown, path: string): unknown {\n if (!path) return obj;\n const parts = path.split('.');\n let current: any = obj;\n for (const part of parts) {\n if (current === null || current === undefined) return undefined;\n current = current[part];\n }\n return current;\n }\n\n private assert(result: unknown, assertion: QA.TestAssertion, _context: Record<string, unknown>) {\n const actual = this.getValueByPath(result, assertion.field);\n // Resolve expected value if it's a variable ref? \n const expected = assertion.expectedValue; // Simplify for now\n\n switch (assertion.operator) {\n case 'equals':\n if (actual !== expected) throw new Error(`Assertion failed: ${assertion.field} expected ${expected}, got ${actual}`);\n break;\n case 'not_equals':\n if (actual === expected) throw new Error(`Assertion failed: ${assertion.field} expected not ${expected}, got ${actual}`);\n break;\n case 'contains':\n if (Array.isArray(actual)) {\n if (!actual.includes(expected)) throw new Error(`Assertion failed: ${assertion.field} array does not contain ${expected}`);\n } else if (typeof actual === 'string') {\n if (!actual.includes(String(expected))) throw new Error(`Assertion failed: ${assertion.field} string does not contain ${expected}`);\n }\n break;\n case 'not_null':\n if (actual === null || actual === undefined) throw new Error(`Assertion failed: ${assertion.field} is null`);\n break;\n case 'is_null':\n if (actual !== null && actual !== undefined) throw new Error(`Assertion failed: ${assertion.field} is not null`);\n break;\n // ... Add other operators\n default:\n throw new Error(`Unknown assertion operator: ${assertion.operator}`);\n }\n }\n}\n","import { QA } from '@objectstack/spec';\nimport { TestExecutionAdapter } from './adapter.js';\n\nexport class HttpTestAdapter implements TestExecutionAdapter {\n constructor(private baseUrl: string, private authToken?: string) {}\n\n async execute(action: QA.TestAction, _context: Record<string, unknown>): Promise<unknown> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n if (this.authToken) {\n headers['Authorization'] = `Bearer ${this.authToken}`;\n }\n // If action.user is specified, maybe add a specific header for impersonation if supported?\n if (action.user) {\n headers['X-Run-As'] = action.user;\n }\n\n switch (action.type) {\n case 'create_record':\n return this.createRecord(action.target, action.payload || {}, headers);\n case 'update_record':\n return this.updateRecord(action.target, action.payload || {}, headers);\n case 'delete_record':\n return this.deleteRecord(action.target, action.payload || {}, headers);\n case 'read_record':\n return this.readRecord(action.target, action.payload || {}, headers);\n case 'query_records':\n return this.queryRecords(action.target, action.payload || {}, headers);\n case 'api_call':\n return this.rawApiCall(action.target, action.payload || {}, headers);\n case 'wait':\n const ms = Number(action.payload?.duration || 1000);\n return new Promise(resolve => setTimeout(() => resolve({ waited: ms }), ms));\n default:\n throw new Error(`Unsupported action type in HttpAdapter: ${action.type}`);\n }\n }\n\n private async createRecord(objectName: string, data: Record<string, unknown>, headers: Record<string, string>) {\n const response = await fetch(`${this.baseUrl}/api/data/${objectName}`, {\n method: 'POST',\n headers,\n body: JSON.stringify(data)\n });\n return this.handleResponse(response);\n }\n\n private async updateRecord(objectName: string, data: Record<string, unknown>, headers: Record<string, string>) {\n const id = data._id || data.id;\n if (!id) throw new Error('Update record requires _id or id in payload');\n const response = await fetch(`${this.baseUrl}/api/data/${objectName}/${id}`, {\n method: 'PUT',\n headers,\n body: JSON.stringify(data)\n });\n return this.handleResponse(response);\n }\n\n private async deleteRecord(objectName: string, data: Record<string, unknown>, headers: Record<string, string>) {\n const id = data._id || data.id;\n if (!id) throw new Error('Delete record requires _id or id in payload');\n const response = await fetch(`${this.baseUrl}/api/data/${objectName}/${id}`, {\n method: 'DELETE',\n headers\n });\n return this.handleResponse(response);\n }\n\n private async readRecord(objectName: string, data: Record<string, unknown>, headers: Record<string, string>) {\n const id = data._id || data.id;\n if (!id) throw new Error('Read record requires _id or id in payload');\n const response = await fetch(`${this.baseUrl}/api/data/${objectName}/${id}`, {\n method: 'GET',\n headers\n });\n return this.handleResponse(response);\n }\n\n private async queryRecords(objectName: string, data: Record<string, unknown>, headers: Record<string, string>) {\n // Assuming query via POST or GraphQL-like endpoint\n const response = await fetch(`${this.baseUrl}/api/data/${objectName}/query`, {\n method: 'POST',\n headers,\n body: JSON.stringify(data)\n });\n return this.handleResponse(response);\n }\n\n private async rawApiCall(endpoint: string, data: Record<string, unknown>, headers: Record<string, string>) {\n const method = (data.method as string) || 'GET';\n const body = data.body ? JSON.stringify(data.body) : undefined;\n const url = endpoint.startsWith('http') ? endpoint : `${this.baseUrl}${endpoint}`;\n \n const response = await fetch(url, {\n method,\n headers,\n body\n });\n return this.handleResponse(response);\n }\n\n private async handleResponse(response: Response) {\n if (!response.ok) {\n const text = await response.text();\n throw new Error(`HTTP Error ${response.status}: ${text}`);\n }\n const contentType = response.headers.get('content-type');\n if (contentType && contentType.includes('application/json')) {\n return response.json();\n }\n return response.text();\n }\n}\n","import type { Logger } from '@objectstack/spec/contracts';\nimport type { PluginMetadata } from '../plugin-loader.js';\n\n// Conditionally import crypto for Node.js environments\nlet cryptoModule: typeof import('crypto') | null = null;\n\n\n/**\n * Plugin Signature Configuration\n * Controls how plugin signatures are verified\n */\nexport interface PluginSignatureConfig {\n /**\n * Map of publisher IDs to their trusted public keys\n * Format: { 'com.objectstack': '-----BEGIN PUBLIC KEY-----...' }\n */\n trustedPublicKeys: Map<string, string>;\n \n /**\n * Signature algorithm to use\n * - RS256: RSA with SHA-256\n * - ES256: ECDSA with SHA-256\n */\n algorithm: 'RS256' | 'ES256';\n \n /**\n * Strict mode: reject plugins without signatures\n * - true: All plugins must be signed\n * - false: Unsigned plugins are allowed with warning\n */\n strictMode: boolean;\n \n /**\n * Allow self-signed plugins in development\n */\n allowSelfSigned?: boolean;\n}\n\n/**\n * Plugin Signature Verification Result\n */\nexport interface SignatureVerificationResult {\n verified: boolean;\n error?: string;\n publisherId?: string;\n algorithm?: string;\n signedAt?: Date;\n}\n\n/**\n * Plugin Signature Verifier\n * \n * Implements cryptographic verification of plugin signatures to ensure:\n * 1. Plugin integrity - code hasn't been tampered with\n * 2. Publisher authenticity - plugin comes from trusted source\n * 3. Non-repudiation - publisher cannot deny signing\n * \n * Architecture:\n * - Uses Node.js crypto module for signature verification\n * - Supports RSA (RS256) and ECDSA (ES256) algorithms\n * - Verifies against trusted public key registry\n * - Computes hash of plugin code for integrity check\n * \n * Security Model:\n * - Public keys are pre-registered and trusted\n * - Plugin signature is verified before loading\n * - Strict mode rejects unsigned plugins\n * - Development mode allows self-signed plugins\n */\nexport class PluginSignatureVerifier {\n private config: PluginSignatureConfig;\n private logger: Logger;\n \n constructor(config: PluginSignatureConfig, logger: Logger) {\n this.config = config;\n this.logger = logger;\n \n this.validateConfig();\n }\n \n /**\n * Verify plugin signature\n * \n * @param plugin - Plugin metadata with signature\n * @returns Verification result\n * @throws Error if verification fails in strict mode\n */\n async verifyPluginSignature(plugin: PluginMetadata): Promise<SignatureVerificationResult> {\n // Handle unsigned plugins\n if (!plugin.signature) {\n return this.handleUnsignedPlugin(plugin);\n }\n \n try {\n // 1. Extract publisher ID from plugin name (reverse domain notation)\n const publisherId = this.extractPublisherId(plugin.name);\n \n // 2. Get trusted public key for publisher\n const publicKey = this.config.trustedPublicKeys.get(publisherId);\n if (!publicKey) {\n const error = `No trusted public key for publisher: ${publisherId}`;\n this.logger.warn(error, { plugin: plugin.name, publisherId });\n \n if (this.config.strictMode && !this.config.allowSelfSigned) {\n throw new Error(error);\n }\n \n return {\n verified: false,\n error,\n publisherId,\n };\n }\n \n // 3. Compute plugin code hash\n const pluginHash = this.computePluginHash(plugin);\n \n // 4. Verify signature using crypto module\n const isValid = await this.verifyCryptoSignature(\n pluginHash,\n plugin.signature,\n publicKey\n );\n \n if (!isValid) {\n const error = `Signature verification failed for plugin: ${plugin.name}`;\n this.logger.error(error, undefined, { plugin: plugin.name, publisherId });\n throw new Error(error);\n }\n \n this.logger.info(`✅ Plugin signature verified: ${plugin.name}`, {\n plugin: plugin.name,\n publisherId,\n algorithm: this.config.algorithm,\n });\n \n return {\n verified: true,\n publisherId,\n algorithm: this.config.algorithm,\n };\n \n } catch (error) {\n this.logger.error(`Signature verification error: ${plugin.name}`, error as Error);\n \n if (this.config.strictMode) {\n throw error;\n }\n \n return {\n verified: false,\n error: (error as Error).message,\n };\n }\n }\n \n /**\n * Register a trusted public key for a publisher\n */\n registerPublicKey(publisherId: string, publicKey: string): void {\n this.config.trustedPublicKeys.set(publisherId, publicKey);\n this.logger.info(`Trusted public key registered for: ${publisherId}`);\n }\n \n /**\n * Remove a trusted public key\n */\n revokePublicKey(publisherId: string): void {\n this.config.trustedPublicKeys.delete(publisherId);\n this.logger.warn(`Public key revoked for: ${publisherId}`);\n }\n \n /**\n * Get list of trusted publishers\n */\n getTrustedPublishers(): string[] {\n return Array.from(this.config.trustedPublicKeys.keys());\n }\n \n // Private methods\n \n private handleUnsignedPlugin(plugin: PluginMetadata): SignatureVerificationResult {\n if (this.config.strictMode) {\n const error = `Plugin missing signature (strict mode): ${plugin.name}`;\n this.logger.error(error, undefined, { plugin: plugin.name });\n throw new Error(error);\n }\n \n this.logger.warn(`⚠️ Plugin not signed: ${plugin.name}`, {\n plugin: plugin.name,\n recommendation: 'Consider signing plugins for production environments',\n });\n \n return {\n verified: false,\n error: 'Plugin not signed',\n };\n }\n \n private extractPublisherId(pluginName: string): string {\n // Extract publisher from reverse domain notation\n // Example: \"com.objectstack.engine.objectql\" -> \"com.objectstack\"\n const parts = pluginName.split('.');\n \n if (parts.length < 2) {\n throw new Error(`Invalid plugin name format: ${pluginName} (expected reverse domain notation)`);\n }\n \n // Return first two parts (domain reversed)\n return `${parts[0]}.${parts[1]}`;\n }\n \n private computePluginHash(plugin: PluginMetadata): string {\n // In browser environment, use SubtleCrypto\n if (typeof (globalThis as any).window !== 'undefined') {\n return this.computePluginHashBrowser(plugin);\n }\n \n // In Node.js environment, use crypto module\n return this.computePluginHashNode(plugin);\n }\n \n private computePluginHashNode(plugin: PluginMetadata): string {\n // Use pre-loaded crypto module\n if (!cryptoModule) {\n this.logger.warn('crypto module not available, using fallback hash');\n return this.computePluginHashFallback(plugin);\n }\n \n // Compute hash of plugin code\n const pluginCode = this.serializePluginCode(plugin);\n return cryptoModule.createHash('sha256').update(pluginCode).digest('hex');\n }\n \n private computePluginHashBrowser(plugin: PluginMetadata): string {\n // Browser environment - use simple hash for now\n // In production, should use SubtleCrypto for proper cryptographic hash\n this.logger.debug('Using browser hash (SubtleCrypto integration pending)');\n return this.computePluginHashFallback(plugin);\n }\n \n private computePluginHashFallback(plugin: PluginMetadata): string {\n // Simple hash fallback (not cryptographically secure)\n const pluginCode = this.serializePluginCode(plugin);\n let hash = 0;\n \n for (let i = 0; i < pluginCode.length; i++) {\n const char = pluginCode.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n \n return hash.toString(16);\n }\n \n private serializePluginCode(plugin: PluginMetadata): string {\n // Serialize plugin code for hashing\n // Include init, start, destroy functions\n const parts: string[] = [\n plugin.name,\n plugin.version,\n plugin.init.toString(),\n ];\n \n if (plugin.start) {\n parts.push(plugin.start.toString());\n }\n \n if (plugin.destroy) {\n parts.push(plugin.destroy.toString());\n }\n \n return parts.join('|');\n }\n \n private async verifyCryptoSignature(\n data: string,\n signature: string,\n publicKey: string\n ): Promise<boolean> {\n // In browser environment, use SubtleCrypto\n if (typeof (globalThis as any).window !== 'undefined') {\n return this.verifyCryptoSignatureBrowser(data, signature, publicKey);\n }\n \n // In Node.js environment, use crypto module\n return this.verifyCryptoSignatureNode(data, signature, publicKey);\n }\n \n private async verifyCryptoSignatureNode(\n data: string,\n signature: string,\n publicKey: string\n ): Promise<boolean> {\n if (!cryptoModule) {\n try {\n // @ts-ignore\n cryptoModule = await import('crypto');\n } catch (e) {\n // ignore\n }\n }\n\n if (!cryptoModule) {\n this.logger.error('Crypto module not available for signature verification');\n return false;\n }\n \n try {\n // Create verify object based on algorithm\n if (this.config.algorithm === 'ES256') {\n // ECDSA verification - requires lowercase 'sha256'\n const verify = cryptoModule.createVerify('sha256');\n verify.update(data);\n return verify.verify(\n {\n key: publicKey,\n format: 'pem',\n type: 'spki',\n },\n signature,\n 'base64'\n );\n } else {\n // RSA verification (RS256)\n const verify = cryptoModule.createVerify('RSA-SHA256');\n verify.update(data);\n return verify.verify(publicKey, signature, 'base64');\n }\n } catch (error) {\n this.logger.error('Signature verification failed', error as Error);\n return false;\n }\n }\n \n private async verifyCryptoSignatureBrowser(\n _data: string,\n _signature: string,\n _publicKey: string\n ): Promise<boolean> {\n // Browser implementation using SubtleCrypto\n // TODO: Implement SubtleCrypto-based verification\n this.logger.warn('Browser signature verification not yet implemented');\n return false;\n }\n \n private validateConfig(): void {\n if (!this.config.trustedPublicKeys || this.config.trustedPublicKeys.size === 0) {\n this.logger.warn('No trusted public keys configured - all signatures will fail');\n }\n \n if (!this.config.algorithm) {\n throw new Error('Signature algorithm must be specified');\n }\n \n if (!['RS256', 'ES256'].includes(this.config.algorithm)) {\n throw new Error(`Unsupported algorithm: ${this.config.algorithm}`);\n }\n }\n}\n","import type { Logger } from '@objectstack/spec/contracts';\nimport type { PluginCapability } from '@objectstack/spec/kernel';\nimport type { PluginContext } from '../types.js';\n\n/**\n * Plugin Permissions\n * Defines what actions a plugin is allowed to perform\n */\nexport interface PluginPermissions {\n canAccessService(serviceName: string): boolean;\n canTriggerHook(hookName: string): boolean;\n canReadFile(path: string): boolean;\n canWriteFile(path: string): boolean;\n canNetworkRequest(url: string): boolean;\n}\n\n/**\n * Permission Check Result\n */\nexport interface PermissionCheckResult {\n allowed: boolean;\n reason?: string;\n capability?: string;\n}\n\n/**\n * Plugin Permission Enforcer\n * \n * Implements capability-based security model to enforce:\n * 1. Service access control - which services a plugin can use\n * 2. Hook restrictions - which hooks a plugin can trigger\n * 3. File system permissions - what files a plugin can read/write\n * 4. Network permissions - what URLs a plugin can access\n * \n * Architecture:\n * - Uses capability declarations from plugin manifest\n * - Checks permissions before allowing operations\n * - Logs all permission denials for security audit\n * - Supports allowlist and denylist patterns\n * \n * Security Model:\n * - Principle of least privilege - plugins get minimal permissions\n * - Explicit declaration - all capabilities must be declared\n * - Runtime enforcement - checks happen at operation time\n * - Audit trail - all denials are logged\n * \n * Usage:\n * ```typescript\n * const enforcer = new PluginPermissionEnforcer(logger);\n * enforcer.registerPluginPermissions(pluginName, capabilities);\n * enforcer.enforceServiceAccess(pluginName, 'database');\n * ```\n */\nexport class PluginPermissionEnforcer {\n private logger: Logger;\n private permissionRegistry: Map<string, PluginPermissions> = new Map();\n private capabilityRegistry: Map<string, PluginCapability[]> = new Map();\n \n constructor(logger: Logger) {\n this.logger = logger;\n }\n \n /**\n * Register plugin capabilities and build permission set\n * \n * @param pluginName - Plugin identifier\n * @param capabilities - Array of capability declarations\n */\n registerPluginPermissions(pluginName: string, capabilities: PluginCapability[]): void {\n this.capabilityRegistry.set(pluginName, capabilities);\n \n const permissions: PluginPermissions = {\n canAccessService: (service) => this.checkServiceAccess(capabilities, service),\n canTriggerHook: (hook) => this.checkHookAccess(capabilities, hook),\n canReadFile: (path) => this.checkFileRead(capabilities, path),\n canWriteFile: (path) => this.checkFileWrite(capabilities, path),\n canNetworkRequest: (url) => this.checkNetworkAccess(capabilities, url),\n };\n \n this.permissionRegistry.set(pluginName, permissions);\n \n this.logger.info(`Permissions registered for plugin: ${pluginName}`, {\n plugin: pluginName,\n capabilityCount: capabilities.length,\n });\n }\n \n /**\n * Enforce service access permission\n * \n * @param pluginName - Plugin requesting access\n * @param serviceName - Service to access\n * @throws Error if permission denied\n */\n enforceServiceAccess(pluginName: string, serviceName: string): void {\n const result = this.checkPermission(pluginName, (perms) => perms.canAccessService(serviceName));\n \n if (!result.allowed) {\n const error = `Permission denied: Plugin ${pluginName} cannot access service ${serviceName}`;\n this.logger.warn(error, {\n plugin: pluginName,\n service: serviceName,\n reason: result.reason,\n });\n throw new Error(error);\n }\n \n this.logger.debug(`Service access granted: ${pluginName} -> ${serviceName}`);\n }\n \n /**\n * Enforce hook trigger permission\n * \n * @param pluginName - Plugin requesting access\n * @param hookName - Hook to trigger\n * @throws Error if permission denied\n */\n enforceHookTrigger(pluginName: string, hookName: string): void {\n const result = this.checkPermission(pluginName, (perms) => perms.canTriggerHook(hookName));\n \n if (!result.allowed) {\n const error = `Permission denied: Plugin ${pluginName} cannot trigger hook ${hookName}`;\n this.logger.warn(error, {\n plugin: pluginName,\n hook: hookName,\n reason: result.reason,\n });\n throw new Error(error);\n }\n \n this.logger.debug(`Hook trigger granted: ${pluginName} -> ${hookName}`);\n }\n \n /**\n * Enforce file read permission\n * \n * @param pluginName - Plugin requesting access\n * @param path - File path to read\n * @throws Error if permission denied\n */\n enforceFileRead(pluginName: string, path: string): void {\n const result = this.checkPermission(pluginName, (perms) => perms.canReadFile(path));\n \n if (!result.allowed) {\n const error = `Permission denied: Plugin ${pluginName} cannot read file ${path}`;\n this.logger.warn(error, {\n plugin: pluginName,\n path,\n reason: result.reason,\n });\n throw new Error(error);\n }\n \n this.logger.debug(`File read granted: ${pluginName} -> ${path}`);\n }\n \n /**\n * Enforce file write permission\n * \n * @param pluginName - Plugin requesting access\n * @param path - File path to write\n * @throws Error if permission denied\n */\n enforceFileWrite(pluginName: string, path: string): void {\n const result = this.checkPermission(pluginName, (perms) => perms.canWriteFile(path));\n \n if (!result.allowed) {\n const error = `Permission denied: Plugin ${pluginName} cannot write file ${path}`;\n this.logger.warn(error, {\n plugin: pluginName,\n path,\n reason: result.reason,\n });\n throw new Error(error);\n }\n \n this.logger.debug(`File write granted: ${pluginName} -> ${path}`);\n }\n \n /**\n * Enforce network request permission\n * \n * @param pluginName - Plugin requesting access\n * @param url - URL to access\n * @throws Error if permission denied\n */\n enforceNetworkRequest(pluginName: string, url: string): void {\n const result = this.checkPermission(pluginName, (perms) => perms.canNetworkRequest(url));\n \n if (!result.allowed) {\n const error = `Permission denied: Plugin ${pluginName} cannot access URL ${url}`;\n this.logger.warn(error, {\n plugin: pluginName,\n url,\n reason: result.reason,\n });\n throw new Error(error);\n }\n \n this.logger.debug(`Network request granted: ${pluginName} -> ${url}`);\n }\n \n /**\n * Get plugin capabilities\n * \n * @param pluginName - Plugin identifier\n * @returns Array of capabilities or undefined\n */\n getPluginCapabilities(pluginName: string): PluginCapability[] | undefined {\n return this.capabilityRegistry.get(pluginName);\n }\n \n /**\n * Get plugin permissions\n * \n * @param pluginName - Plugin identifier\n * @returns Permissions object or undefined\n */\n getPluginPermissions(pluginName: string): PluginPermissions | undefined {\n return this.permissionRegistry.get(pluginName);\n }\n \n /**\n * Revoke all permissions for a plugin\n * \n * @param pluginName - Plugin identifier\n */\n revokePermissions(pluginName: string): void {\n this.permissionRegistry.delete(pluginName);\n this.capabilityRegistry.delete(pluginName);\n this.logger.warn(`Permissions revoked for plugin: ${pluginName}`);\n }\n \n // Private methods\n \n private checkPermission(\n pluginName: string,\n check: (perms: PluginPermissions) => boolean\n ): PermissionCheckResult {\n const permissions = this.permissionRegistry.get(pluginName);\n \n if (!permissions) {\n return {\n allowed: false,\n reason: 'Plugin permissions not registered',\n };\n }\n \n const allowed = check(permissions);\n \n return {\n allowed,\n reason: allowed ? undefined : 'No matching capability found',\n };\n }\n \n private checkServiceAccess(capabilities: PluginCapability[], serviceName: string): boolean {\n // Check if plugin has capability to access this service\n return capabilities.some(cap => {\n const protocolId = cap.protocol.id;\n \n // Check for wildcard service access\n if (protocolId.includes('protocol.service.all')) {\n return true;\n }\n \n // Check for specific service protocol\n if (protocolId.includes(`protocol.service.${serviceName}`)) {\n return true;\n }\n \n // Check for service category match\n const serviceCategory = serviceName.split('.')[0];\n if (protocolId.includes(`protocol.service.${serviceCategory}`)) {\n return true;\n }\n \n return false;\n });\n }\n \n private checkHookAccess(capabilities: PluginCapability[], hookName: string): boolean {\n // Check if plugin has capability to trigger this hook\n return capabilities.some(cap => {\n const protocolId = cap.protocol.id;\n \n // Check for wildcard hook access\n if (protocolId.includes('protocol.hook.all')) {\n return true;\n }\n \n // Check for specific hook protocol\n if (protocolId.includes(`protocol.hook.${hookName}`)) {\n return true;\n }\n \n // Check for hook category match\n const hookCategory = hookName.split(':')[0];\n if (protocolId.includes(`protocol.hook.${hookCategory}`)) {\n return true;\n }\n \n return false;\n });\n }\n \n private checkFileRead(capabilities: PluginCapability[], _path: string): boolean {\n // Check if plugin has capability to read this file\n return capabilities.some(cap => {\n const protocolId = cap.protocol.id;\n \n // Check for file read capability\n if (protocolId.includes('protocol.filesystem.read')) {\n // TODO: Add path pattern matching\n return true;\n }\n \n return false;\n });\n }\n \n private checkFileWrite(capabilities: PluginCapability[], _path: string): boolean {\n // Check if plugin has capability to write this file\n return capabilities.some(cap => {\n const protocolId = cap.protocol.id;\n \n // Check for file write capability\n if (protocolId.includes('protocol.filesystem.write')) {\n // TODO: Add path pattern matching\n return true;\n }\n \n return false;\n });\n }\n \n private checkNetworkAccess(capabilities: PluginCapability[], _url: string): boolean {\n // Check if plugin has capability to access this URL\n return capabilities.some(cap => {\n const protocolId = cap.protocol.id;\n \n // Check for network capability\n if (protocolId.includes('protocol.network')) {\n // TODO: Add URL pattern matching\n return true;\n }\n \n return false;\n });\n }\n}\n\n/**\n * Secure Plugin Context\n * Wraps PluginContext with permission checks\n */\nexport class SecurePluginContext implements PluginContext {\n constructor(\n private pluginName: string,\n private permissionEnforcer: PluginPermissionEnforcer,\n private baseContext: PluginContext\n ) {}\n \n registerService(name: string, service: any): void {\n // No permission check for service registration (handled during init)\n this.baseContext.registerService(name, service);\n }\n \n getService<T>(name: string): T {\n // Check permission before accessing service\n this.permissionEnforcer.enforceServiceAccess(this.pluginName, name);\n return this.baseContext.getService<T>(name);\n }\n \n getServices(): Map<string, any> {\n // Return all services (no permission check for listing)\n return this.baseContext.getServices();\n }\n \n hook(name: string, handler: (...args: any[]) => void | Promise<void>): void {\n // No permission check for registering hooks (handled during init)\n this.baseContext.hook(name, handler);\n }\n \n async trigger(name: string, ...args: any[]): Promise<void> {\n // Check permission before triggering hook\n this.permissionEnforcer.enforceHookTrigger(this.pluginName, name);\n await this.baseContext.trigger(name, ...args);\n }\n \n get logger() {\n return this.baseContext.logger;\n }\n \n getKernel() {\n return this.baseContext.getKernel();\n }\n}\n\n/**\n * Create a plugin permission enforcer\n * \n * @param logger - Logger instance\n * @returns Plugin permission enforcer\n */\nexport function createPluginPermissionEnforcer(logger: Logger): PluginPermissionEnforcer {\n return new PluginPermissionEnforcer(logger);\n}\n","import type { \n Permission,\n PermissionSet,\n PermissionAction,\n ResourceType\n} from '@objectstack/spec/kernel';\nimport type { ObjectLogger } from '../logger.js';\n\n/**\n * Permission Grant\n * Represents a granted permission at runtime\n */\nexport interface PermissionGrant {\n permissionId: string;\n pluginId: string;\n grantedAt: Date;\n grantedBy?: string;\n expiresAt?: Date;\n conditions?: Record<string, any>;\n}\n\n/**\n * Permission Check Result\n */\nexport interface PermissionCheckResult {\n allowed: boolean;\n reason?: string;\n requiredPermission?: string;\n grantedPermissions?: string[];\n}\n\n/**\n * Plugin Permission Manager\n * \n * Manages fine-grained permissions for plugin security and access control\n */\nexport class PluginPermissionManager {\n private logger: ObjectLogger;\n \n // Plugin permission definitions\n private permissionSets = new Map<string, PermissionSet>();\n \n // Granted permissions (pluginId -> Set of permission IDs)\n private grants = new Map<string, Set<string>>();\n \n // Permission grant details\n private grantDetails = new Map<string, PermissionGrant>();\n\n constructor(logger: ObjectLogger) {\n this.logger = logger.child({ component: 'PermissionManager' });\n }\n\n /**\n * Register permission requirements for a plugin\n */\n registerPermissions(pluginId: string, permissionSet: PermissionSet): void {\n this.permissionSets.set(pluginId, permissionSet);\n \n this.logger.info('Permissions registered for plugin', { \n pluginId,\n permissionCount: permissionSet.permissions.length\n });\n }\n\n /**\n * Grant a permission to a plugin\n */\n grantPermission(\n pluginId: string,\n permissionId: string,\n grantedBy?: string,\n expiresAt?: Date\n ): void {\n // Verify permission exists in plugin's declared permissions\n const permissionSet = this.permissionSets.get(pluginId);\n if (!permissionSet) {\n throw new Error(`No permissions registered for plugin: ${pluginId}`);\n }\n\n const permission = permissionSet.permissions.find(p => p.id === permissionId);\n if (!permission) {\n throw new Error(`Permission ${permissionId} not declared by plugin ${pluginId}`);\n }\n\n // Create grant\n if (!this.grants.has(pluginId)) {\n this.grants.set(pluginId, new Set());\n }\n this.grants.get(pluginId)!.add(permissionId);\n\n // Store grant details\n const grantKey = `${pluginId}:${permissionId}`;\n this.grantDetails.set(grantKey, {\n permissionId,\n pluginId,\n grantedAt: new Date(),\n grantedBy,\n expiresAt,\n });\n\n this.logger.info('Permission granted', { \n pluginId, \n permissionId,\n grantedBy \n });\n }\n\n /**\n * Revoke a permission from a plugin\n */\n revokePermission(pluginId: string, permissionId: string): void {\n const grants = this.grants.get(pluginId);\n if (grants) {\n grants.delete(permissionId);\n \n const grantKey = `${pluginId}:${permissionId}`;\n this.grantDetails.delete(grantKey);\n\n this.logger.info('Permission revoked', { pluginId, permissionId });\n }\n }\n\n /**\n * Grant all permissions for a plugin\n */\n grantAllPermissions(pluginId: string, grantedBy?: string): void {\n const permissionSet = this.permissionSets.get(pluginId);\n if (!permissionSet) {\n throw new Error(`No permissions registered for plugin: ${pluginId}`);\n }\n\n for (const permission of permissionSet.permissions) {\n this.grantPermission(pluginId, permission.id, grantedBy);\n }\n\n this.logger.info('All permissions granted', { pluginId, grantedBy });\n }\n\n /**\n * Check if a plugin has a specific permission\n */\n hasPermission(pluginId: string, permissionId: string): boolean {\n const grants = this.grants.get(pluginId);\n if (!grants) {\n return false;\n }\n\n // Check if granted\n if (!grants.has(permissionId)) {\n return false;\n }\n\n // Check expiration\n const grantKey = `${pluginId}:${permissionId}`;\n const grantDetails = this.grantDetails.get(grantKey);\n if (grantDetails?.expiresAt && grantDetails.expiresAt < new Date()) {\n this.revokePermission(pluginId, permissionId);\n return false;\n }\n\n return true;\n }\n\n /**\n * Check if plugin can perform an action on a resource\n */\n checkAccess(\n pluginId: string,\n resource: ResourceType,\n action: PermissionAction,\n resourceId?: string\n ): PermissionCheckResult {\n const permissionSet = this.permissionSets.get(pluginId);\n if (!permissionSet) {\n return {\n allowed: false,\n reason: 'No permissions registered for plugin',\n };\n }\n\n // Find matching permissions\n const matchingPermissions = permissionSet.permissions.filter(p => {\n // Check resource type\n if (p.resource !== resource) {\n return false;\n }\n\n // Check action\n if (!p.actions.includes(action)) {\n return false;\n }\n\n // Check resource filter if specified\n if (resourceId && p.filter?.resourceIds) {\n if (!p.filter.resourceIds.includes(resourceId)) {\n return false;\n }\n }\n\n return true;\n });\n\n if (matchingPermissions.length === 0) {\n return {\n allowed: false,\n reason: `No permission found for ${action} on ${resource}`,\n };\n }\n\n // Check if any matching permission is granted\n const grantedPermissions = matchingPermissions.filter(p => \n this.hasPermission(pluginId, p.id)\n );\n\n if (grantedPermissions.length === 0) {\n return {\n allowed: false,\n reason: 'Required permissions not granted',\n requiredPermission: matchingPermissions[0].id,\n };\n }\n\n return {\n allowed: true,\n grantedPermissions: grantedPermissions.map(p => p.id),\n };\n }\n\n /**\n * Get all permissions for a plugin\n */\n getPluginPermissions(pluginId: string): Permission[] {\n const permissionSet = this.permissionSets.get(pluginId);\n return permissionSet?.permissions || [];\n }\n\n /**\n * Get granted permissions for a plugin\n */\n getGrantedPermissions(pluginId: string): string[] {\n const grants = this.grants.get(pluginId);\n return grants ? Array.from(grants) : [];\n }\n\n /**\n * Get required but not granted permissions\n */\n getMissingPermissions(pluginId: string): Permission[] {\n const permissionSet = this.permissionSets.get(pluginId);\n if (!permissionSet) {\n return [];\n }\n\n const granted = this.grants.get(pluginId) || new Set();\n \n return permissionSet.permissions.filter(p => \n p.required && !granted.has(p.id)\n );\n }\n\n /**\n * Check if all required permissions are granted\n */\n hasAllRequiredPermissions(pluginId: string): boolean {\n return this.getMissingPermissions(pluginId).length === 0;\n }\n\n /**\n * Get permission grant details\n */\n getGrantDetails(pluginId: string, permissionId: string): PermissionGrant | undefined {\n const grantKey = `${pluginId}:${permissionId}`;\n return this.grantDetails.get(grantKey);\n }\n\n /**\n * Validate permission against scope constraints\n */\n validatePermissionScope(\n permission: Permission,\n context: {\n tenantId?: string;\n userId?: string;\n resourceId?: string;\n }\n ): boolean {\n switch (permission.scope) {\n case 'global':\n return true;\n\n case 'tenant':\n return !!context.tenantId;\n\n case 'user':\n return !!context.userId;\n\n case 'resource':\n return !!context.resourceId;\n\n case 'plugin':\n return true;\n\n default:\n return false;\n }\n }\n\n /**\n * Clear all permissions for a plugin\n */\n clearPluginPermissions(pluginId: string): void {\n this.permissionSets.delete(pluginId);\n \n const grants = this.grants.get(pluginId);\n if (grants) {\n for (const permissionId of grants) {\n const grantKey = `${pluginId}:${permissionId}`;\n this.grantDetails.delete(grantKey);\n }\n this.grants.delete(pluginId);\n }\n\n this.logger.info('All permissions cleared', { pluginId });\n }\n\n /**\n * Shutdown permission manager\n */\n shutdown(): void {\n this.permissionSets.clear();\n this.grants.clear();\n this.grantDetails.clear();\n \n this.logger.info('Permission manager shutdown complete');\n }\n}\n","import type { \n SandboxConfig\n} from '@objectstack/spec/kernel';\nimport type { ObjectLogger } from '../logger.js';\nimport { getMemoryUsage } from '../utils/env.js';\n\n/**\n * Resource Usage Statistics\n */\nexport interface ResourceUsage {\n memory: {\n current: number;\n peak: number;\n limit?: number;\n };\n cpu: {\n current: number;\n average: number;\n limit?: number;\n };\n connections: {\n current: number;\n limit?: number;\n };\n}\n\n/**\n * Sandbox Execution Context\n * Represents an isolated execution environment for a plugin\n */\nexport interface SandboxContext {\n pluginId: string;\n config: SandboxConfig;\n startTime: Date;\n resourceUsage: ResourceUsage;\n}\n\n/**\n * Plugin Sandbox Runtime\n * \n * Provides isolated execution environments for plugins with resource limits\n * and access controls\n */\nexport class PluginSandboxRuntime {\n private logger: ObjectLogger;\n \n // Active sandboxes (pluginId -> context)\n private sandboxes = new Map<string, SandboxContext>();\n \n // Resource monitoring intervals\n private monitoringIntervals = new Map<string, NodeJS.Timeout>();\n\n constructor(logger: ObjectLogger) {\n this.logger = logger.child({ component: 'SandboxRuntime' });\n }\n\n /**\n * Create a sandbox for a plugin\n */\n createSandbox(pluginId: string, config: SandboxConfig): SandboxContext {\n if (this.sandboxes.has(pluginId)) {\n throw new Error(`Sandbox already exists for plugin: ${pluginId}`);\n }\n\n const context: SandboxContext = {\n pluginId,\n config,\n startTime: new Date(),\n resourceUsage: {\n memory: { current: 0, peak: 0, limit: config.memory?.maxHeap },\n cpu: { current: 0, average: 0, limit: config.cpu?.maxCpuPercent },\n connections: { current: 0, limit: config.network?.maxConnections },\n },\n };\n\n this.sandboxes.set(pluginId, context);\n\n // Start resource monitoring\n this.startResourceMonitoring(pluginId);\n\n this.logger.info('Sandbox created', { \n pluginId,\n level: config.level,\n memoryLimit: config.memory?.maxHeap,\n cpuLimit: config.cpu?.maxCpuPercent\n });\n\n return context;\n }\n\n /**\n * Destroy a sandbox\n */\n destroySandbox(pluginId: string): void {\n const context = this.sandboxes.get(pluginId);\n if (!context) {\n return;\n }\n\n // Stop monitoring\n this.stopResourceMonitoring(pluginId);\n\n this.sandboxes.delete(pluginId);\n\n this.logger.info('Sandbox destroyed', { pluginId });\n }\n\n /**\n * Check if resource access is allowed\n */\n checkResourceAccess(\n pluginId: string,\n resourceType: 'file' | 'network' | 'process' | 'env',\n resourcePath?: string\n ): { allowed: boolean; reason?: string } {\n const context = this.sandboxes.get(pluginId);\n if (!context) {\n return { allowed: false, reason: 'Sandbox not found' };\n }\n\n const { config } = context;\n\n switch (resourceType) {\n case 'file':\n return this.checkFileAccess(config, resourcePath);\n \n case 'network':\n return this.checkNetworkAccess(config, resourcePath);\n \n case 'process':\n return this.checkProcessAccess(config);\n \n case 'env':\n return this.checkEnvAccess(config, resourcePath);\n \n default:\n return { allowed: false, reason: 'Unknown resource type' };\n }\n }\n\n /**\n * Check file system access\n * WARNING: Uses simple prefix matching. For production, use proper path\n * resolution with path.resolve() and path.normalize() to prevent traversal.\n */\n private checkFileAccess(\n config: SandboxConfig,\n path?: string\n ): { allowed: boolean; reason?: string } {\n if (config.level === 'none') {\n return { allowed: true };\n }\n\n if (!config.filesystem) {\n return { allowed: false, reason: 'File system access not configured' };\n }\n\n // If no path specified, check general access\n if (!path) {\n return { allowed: config.filesystem.mode !== 'none' };\n }\n\n // TODO: Use path.resolve() and path.normalize() for production\n // Check allowed paths\n const allowedPaths = config.filesystem.allowedPaths || [];\n const isAllowed = allowedPaths.some(allowed => {\n // Simple prefix matching - vulnerable to traversal attacks\n // TODO: Use proper path resolution\n return path.startsWith(allowed);\n });\n\n if (allowedPaths.length > 0 && !isAllowed) {\n return { \n allowed: false, \n reason: `Path not in allowed list: ${path}` \n };\n }\n\n // Check denied paths\n const deniedPaths = config.filesystem.deniedPaths || [];\n const isDenied = deniedPaths.some(denied => {\n return path.startsWith(denied);\n });\n\n if (isDenied) {\n return { \n allowed: false, \n reason: `Path is explicitly denied: ${path}` \n };\n }\n\n return { allowed: true };\n }\n\n /**\n * Check network access\n * WARNING: Uses simple string matching. For production, use proper URL\n * parsing with new URL() and check hostname property.\n */\n private checkNetworkAccess(\n config: SandboxConfig,\n url?: string\n ): { allowed: boolean; reason?: string } {\n if (config.level === 'none') {\n return { allowed: true };\n }\n\n if (!config.network) {\n return { allowed: false, reason: 'Network access not configured' };\n }\n\n // Check if network access is enabled\n if (config.network.mode === 'none') {\n return { allowed: false, reason: 'Network access disabled' };\n }\n\n // If no URL specified, check general access\n if (!url) {\n return { allowed: (config.network.mode as string) !== 'none' };\n }\n\n // TODO: Use new URL() and check hostname property for production\n // Check allowed hosts\n const allowedHosts = config.network.allowedHosts || [];\n if (allowedHosts.length > 0) {\n const isAllowed = allowedHosts.some(host => {\n // Simple string matching - vulnerable to bypass\n // TODO: Use proper URL parsing\n return url.includes(host);\n });\n\n if (!isAllowed) {\n return { \n allowed: false, \n reason: `Host not in allowed list: ${url}` \n };\n }\n }\n\n // Check denied hosts\n const deniedHosts = config.network.deniedHosts || [];\n const isDenied = deniedHosts.some(host => {\n return url.includes(host);\n });\n\n if (isDenied) {\n return { \n allowed: false, \n reason: `Host is blocked: ${url}` \n };\n }\n\n return { allowed: true };\n }\n\n /**\n * Check process spawning access\n */\n private checkProcessAccess(\n config: SandboxConfig\n ): { allowed: boolean; reason?: string } {\n if (config.level === 'none') {\n return { allowed: true };\n }\n\n if (!config.process) {\n return { allowed: false, reason: 'Process access not configured' };\n }\n\n if (!config.process.allowSpawn) {\n return { allowed: false, reason: 'Process spawning not allowed' };\n }\n\n return { allowed: true };\n }\n\n /**\n * Check environment variable access\n */\n private checkEnvAccess(\n config: SandboxConfig,\n varName?: string\n ): { allowed: boolean; reason?: string } {\n if (config.level === 'none') {\n return { allowed: true };\n }\n\n if (!config.process) {\n return { allowed: false, reason: 'Environment access not configured' };\n }\n\n // If no variable specified, check general access\n if (!varName) {\n return { allowed: true };\n }\n\n // For now, allow all env access if process is configured\n // In a real implementation, would check specific allowed vars\n return { allowed: true };\n }\n\n /**\n * Check resource limits\n */\n checkResourceLimits(pluginId: string): { \n withinLimits: boolean; \n violations: string[] \n } {\n const context = this.sandboxes.get(pluginId);\n if (!context) {\n return { withinLimits: true, violations: [] };\n }\n\n const violations: string[] = [];\n const { resourceUsage, config } = context;\n\n // Check memory limit\n if (config.memory?.maxHeap && \n resourceUsage.memory.current > config.memory.maxHeap) {\n violations.push(`Memory limit exceeded: ${resourceUsage.memory.current} > ${config.memory.maxHeap}`);\n }\n\n // Check CPU limit (would need runtime config)\n if (config.runtime?.resourceLimits?.maxCpu && \n resourceUsage.cpu.current > config.runtime.resourceLimits.maxCpu) {\n violations.push(`CPU limit exceeded: ${resourceUsage.cpu.current}% > ${config.runtime.resourceLimits.maxCpu}%`);\n }\n\n // Check connection limit\n if (config.network?.maxConnections && \n resourceUsage.connections.current > config.network.maxConnections) {\n violations.push(`Connection limit exceeded: ${resourceUsage.connections.current} > ${config.network.maxConnections}`);\n }\n\n return {\n withinLimits: violations.length === 0,\n violations,\n };\n }\n\n /**\n * Get resource usage for a plugin\n */\n getResourceUsage(pluginId: string): ResourceUsage | undefined {\n const context = this.sandboxes.get(pluginId);\n return context?.resourceUsage;\n }\n\n /**\n * Start monitoring resource usage\n */\n private startResourceMonitoring(pluginId: string): void {\n // Monitor every 5 seconds\n const interval = setInterval(() => {\n this.updateResourceUsage(pluginId);\n }, 5000);\n\n this.monitoringIntervals.set(pluginId, interval);\n }\n\n /**\n * Stop monitoring resource usage\n */\n private stopResourceMonitoring(pluginId: string): void {\n const interval = this.monitoringIntervals.get(pluginId);\n if (interval) {\n clearInterval(interval);\n this.monitoringIntervals.delete(pluginId);\n }\n }\n\n /**\n * Update resource usage statistics\n * \n * NOTE: Currently uses global process.memoryUsage() which tracks the entire\n * Node.js process, not individual plugins. For production, implement proper\n * per-plugin tracking using V8 heap snapshots or allocation tracking at\n * plugin boundaries.\n */\n private updateResourceUsage(pluginId: string): void {\n const context = this.sandboxes.get(pluginId);\n if (!context) {\n return;\n }\n\n // In a real implementation, this would collect actual metrics\n // For now, this is a placeholder structure\n \n // Update memory usage (global process memory - not per-plugin)\n // TODO: Implement per-plugin memory tracking\n const memoryUsage = getMemoryUsage();\n context.resourceUsage.memory.current = memoryUsage.heapUsed;\n context.resourceUsage.memory.peak = Math.max(\n context.resourceUsage.memory.peak,\n memoryUsage.heapUsed\n );\n\n // Update CPU usage (would use process.cpuUsage() or similar)\n // This is a placeholder - real implementation would track per-plugin CPU\n // TODO: Implement per-plugin CPU tracking\n context.resourceUsage.cpu.current = 0;\n\n // Check for violations\n const { withinLimits, violations } = this.checkResourceLimits(pluginId);\n if (!withinLimits) {\n this.logger.warn('Resource limit violations detected', { \n pluginId, \n violations \n });\n }\n }\n\n /**\n * Get all active sandboxes\n */\n getAllSandboxes(): Map<string, SandboxContext> {\n return new Map(this.sandboxes);\n }\n\n /**\n * Shutdown sandbox runtime\n */\n shutdown(): void {\n // Stop all monitoring\n for (const pluginId of this.monitoringIntervals.keys()) {\n this.stopResourceMonitoring(pluginId);\n }\n\n this.sandboxes.clear();\n \n this.logger.info('Sandbox runtime shutdown complete');\n }\n}\n","import type { \n SecurityVulnerability,\n SecurityScanResult\n} from '@objectstack/spec/kernel';\nimport type { ObjectLogger } from '../logger.js';\n\n/**\n * Scan Target\n */\nexport interface ScanTarget {\n pluginId: string;\n version: string;\n files?: string[];\n dependencies?: Record<string, string>;\n}\n\n/**\n * Security Issue\n */\nexport interface SecurityIssue {\n id: string;\n severity: 'critical' | 'high' | 'medium' | 'low' | 'info';\n category: 'vulnerability' | 'malware' | 'license' | 'code-quality' | 'configuration';\n title: string;\n description: string;\n location?: {\n file?: string;\n line?: number;\n column?: number;\n };\n remediation?: string;\n cve?: string;\n cvss?: number;\n}\n\n/**\n * Plugin Security Scanner\n * \n * Scans plugins for security vulnerabilities, malware, and license issues\n */\nexport class PluginSecurityScanner {\n private logger: ObjectLogger;\n \n // Known vulnerabilities database (CVE cache)\n private vulnerabilityDb = new Map<string, SecurityVulnerability>();\n \n // Scan results cache\n private scanResults = new Map<string, SecurityScanResult>();\n\n private passThreshold: number = 70;\n\n constructor(logger: ObjectLogger, config?: { passThreshold?: number }) {\n this.logger = logger.child({ component: 'SecurityScanner' });\n if (config?.passThreshold !== undefined) {\n this.passThreshold = config.passThreshold;\n }\n }\n\n /**\n * Perform a comprehensive security scan on a plugin\n */\n async scan(target: ScanTarget): Promise<SecurityScanResult> {\n this.logger.info('Starting security scan', { \n pluginId: target.pluginId,\n version: target.version \n });\n\n const issues: SecurityIssue[] = [];\n\n try {\n // 1. Scan for code vulnerabilities\n const codeIssues = await this.scanCode(target);\n issues.push(...codeIssues);\n\n // 2. Scan dependencies for known vulnerabilities\n const depIssues = await this.scanDependencies(target);\n issues.push(...depIssues);\n\n // 3. Scan for malware patterns\n const malwareIssues = await this.scanMalware(target);\n issues.push(...malwareIssues);\n\n // 4. Check license compliance\n const licenseIssues = await this.scanLicenses(target);\n issues.push(...licenseIssues);\n\n // 5. Check configuration security\n const configIssues = await this.scanConfiguration(target);\n issues.push(...configIssues);\n\n // Calculate security score (0-100, higher is better)\n const score = this.calculateSecurityScore(issues);\n\n const result: SecurityScanResult = {\n timestamp: new Date().toISOString(),\n scanner: { name: 'ObjectStack Security Scanner', version: '1.0.0' },\n status: score >= this.passThreshold ? 'passed' : 'failed',\n vulnerabilities: issues.map(issue => ({\n id: issue.id,\n severity: issue.severity,\n category: issue.category,\n title: issue.title,\n description: issue.description,\n location: issue.location ? `${issue.location.file}:${issue.location.line}` : undefined,\n remediation: issue.remediation,\n affectedVersions: [],\n exploitAvailable: false,\n patchAvailable: false,\n })),\n summary: {\n totalVulnerabilities: issues.length,\n criticalCount: issues.filter(i => i.severity === 'critical').length,\n highCount: issues.filter(i => i.severity === 'high').length,\n mediumCount: issues.filter(i => i.severity === 'medium').length,\n lowCount: issues.filter(i => i.severity === 'low').length,\n infoCount: issues.filter(i => i.severity === 'info').length,\n },\n };\n\n this.scanResults.set(`${target.pluginId}:${target.version}`, result);\n\n this.logger.info('Security scan complete', { \n pluginId: target.pluginId,\n score,\n status: result.status,\n summary: result.summary\n });\n\n return result;\n } catch (error) {\n this.logger.error('Security scan failed', { \n pluginId: target.pluginId, \n error \n });\n\n throw error;\n }\n }\n\n /**\n * Scan code for vulnerabilities\n */\n private async scanCode(target: ScanTarget): Promise<SecurityIssue[]> {\n const issues: SecurityIssue[] = [];\n\n // In a real implementation, this would:\n // - Parse code with AST (e.g., using @typescript-eslint/parser)\n // - Check for dangerous patterns (eval, Function constructor, etc.)\n // - Check for XSS vulnerabilities\n // - Check for SQL injection patterns\n // - Check for insecure crypto usage\n // - Check for path traversal vulnerabilities\n\n this.logger.debug('Code scan complete', { \n pluginId: target.pluginId,\n issuesFound: issues.length \n });\n\n return issues;\n }\n\n /**\n * Scan dependencies for known vulnerabilities\n */\n private async scanDependencies(target: ScanTarget): Promise<SecurityIssue[]> {\n const issues: SecurityIssue[] = [];\n\n if (!target.dependencies) {\n return issues;\n }\n\n // In a real implementation, this would:\n // - Query npm audit API\n // - Check GitHub Advisory Database\n // - Check Snyk vulnerability database\n // - Check OSV (Open Source Vulnerabilities)\n\n for (const [depName, version] of Object.entries(target.dependencies)) {\n const vulnKey = `${depName}@${version}`;\n const vulnerability = this.vulnerabilityDb.get(vulnKey);\n\n if (vulnerability) {\n issues.push({\n id: `vuln-${vulnerability.cve || depName}`,\n severity: vulnerability.severity,\n category: 'vulnerability',\n title: `Vulnerable dependency: ${depName}`,\n description: `${depName}@${version} has known security vulnerabilities`,\n remediation: vulnerability.fixedIn \n ? `Upgrade to ${vulnerability.fixedIn.join(' or ')}`\n : 'No fix available',\n cve: vulnerability.cve,\n });\n }\n }\n\n this.logger.debug('Dependency scan complete', { \n pluginId: target.pluginId,\n dependencies: Object.keys(target.dependencies).length,\n vulnerabilities: issues.length \n });\n\n return issues;\n }\n\n /**\n * Scan for malware patterns\n */\n private async scanMalware(target: ScanTarget): Promise<SecurityIssue[]> {\n const issues: SecurityIssue[] = [];\n\n // In a real implementation, this would:\n // - Check for obfuscated code\n // - Check for suspicious network activity patterns\n // - Check for crypto mining patterns\n // - Check for data exfiltration patterns\n // - Use ML-based malware detection\n // - Check file hashes against known malware databases\n\n this.logger.debug('Malware scan complete', { \n pluginId: target.pluginId,\n issuesFound: issues.length \n });\n\n return issues;\n }\n\n /**\n * Check license compliance\n */\n private async scanLicenses(target: ScanTarget): Promise<SecurityIssue[]> {\n const issues: SecurityIssue[] = [];\n\n if (!target.dependencies) {\n return issues;\n }\n\n // In a real implementation, this would:\n // - Check license compatibility\n // - Detect GPL contamination\n // - Flag proprietary dependencies\n // - Check for missing licenses\n // - Verify SPDX identifiers\n\n this.logger.debug('License scan complete', { \n pluginId: target.pluginId,\n issuesFound: issues.length \n });\n\n return issues;\n }\n\n /**\n * Check configuration security\n */\n private async scanConfiguration(target: ScanTarget): Promise<SecurityIssue[]> {\n const issues: SecurityIssue[] = [];\n\n // In a real implementation, this would:\n // - Check for hardcoded secrets\n // - Check for weak permissions\n // - Check for insecure defaults\n // - Check for missing security headers\n // - Check CSP policies\n\n this.logger.debug('Configuration scan complete', { \n pluginId: target.pluginId,\n issuesFound: issues.length \n });\n\n return issues;\n }\n\n /**\n * Calculate security score based on issues\n */\n private calculateSecurityScore(issues: SecurityIssue[]): number {\n // Start with perfect score\n let score = 100;\n\n // Deduct points based on severity\n for (const issue of issues) {\n switch (issue.severity) {\n case 'critical':\n score -= 20;\n break;\n case 'high':\n score -= 10;\n break;\n case 'medium':\n score -= 5;\n break;\n case 'low':\n score -= 2;\n break;\n case 'info':\n score -= 0;\n break;\n }\n }\n\n // Ensure score doesn't go below 0\n return Math.max(0, score);\n }\n\n /**\n * Add a vulnerability to the database\n */\n addVulnerability(\n packageName: string,\n version: string,\n vulnerability: SecurityVulnerability\n ): void {\n const key = `${packageName}@${version}`;\n this.vulnerabilityDb.set(key, vulnerability);\n \n this.logger.debug('Vulnerability added to database', { \n package: packageName, \n version,\n cve: vulnerability.cve \n });\n }\n\n /**\n * Get scan result from cache\n */\n getScanResult(pluginId: string, version: string): SecurityScanResult | undefined {\n return this.scanResults.get(`${pluginId}:${version}`);\n }\n\n /**\n * Clear scan results cache\n */\n clearCache(): void {\n this.scanResults.clear();\n this.logger.debug('Scan results cache cleared');\n }\n\n /**\n * Update vulnerability database from external source\n */\n async updateVulnerabilityDatabase(): Promise<void> {\n this.logger.info('Updating vulnerability database');\n\n // In a real implementation, this would:\n // - Fetch from GitHub Advisory Database\n // - Fetch from npm audit\n // - Fetch from NVD (National Vulnerability Database)\n // - Parse and cache vulnerability data\n\n this.logger.info('Vulnerability database updated', { \n entries: this.vulnerabilityDb.size \n });\n }\n\n /**\n * Shutdown security scanner\n */\n shutdown(): void {\n this.vulnerabilityDb.clear();\n this.scanResults.clear();\n \n this.logger.info('Security scanner shutdown complete');\n }\n}\n","import type { \n PluginHealthStatus, \n PluginHealthCheck, \n PluginHealthReport \n} from '@objectstack/spec/kernel';\nimport type { ObjectLogger } from './logger.js';\nimport type { Plugin } from './types.js';\n\n/**\n * Plugin Health Monitor\n * \n * Monitors plugin health status and performs automatic recovery actions.\n * Implements the advanced lifecycle health monitoring protocol.\n */\nexport class PluginHealthMonitor {\n private logger: ObjectLogger;\n private healthChecks = new Map<string, PluginHealthCheck>();\n private healthStatus = new Map<string, PluginHealthStatus>();\n private healthReports = new Map<string, PluginHealthReport>();\n private checkIntervals = new Map<string, NodeJS.Timeout>();\n private failureCounters = new Map<string, number>();\n private successCounters = new Map<string, number>();\n private restartAttempts = new Map<string, number>();\n\n constructor(logger: ObjectLogger) {\n this.logger = logger.child({ component: 'HealthMonitor' });\n }\n\n /**\n * Register a plugin for health monitoring\n */\n registerPlugin(pluginName: string, config: PluginHealthCheck): void {\n this.healthChecks.set(pluginName, config);\n this.healthStatus.set(pluginName, 'unknown');\n this.failureCounters.set(pluginName, 0);\n this.successCounters.set(pluginName, 0);\n this.restartAttempts.set(pluginName, 0);\n\n this.logger.info('Plugin registered for health monitoring', { \n plugin: pluginName,\n interval: config.interval \n });\n }\n\n /**\n * Start monitoring a plugin\n */\n startMonitoring(pluginName: string, plugin: Plugin): void {\n const config = this.healthChecks.get(pluginName);\n if (!config) {\n this.logger.warn('Cannot start monitoring - plugin not registered', { plugin: pluginName });\n return;\n }\n\n // Clear any existing interval\n this.stopMonitoring(pluginName);\n\n // Set up periodic health checks\n const interval = setInterval(() => {\n this.performHealthCheck(pluginName, plugin, config).catch(error => {\n this.logger.error('Health check failed with error', { \n plugin: pluginName, \n error \n });\n });\n }, config.interval);\n\n this.checkIntervals.set(pluginName, interval);\n this.logger.info('Health monitoring started', { plugin: pluginName });\n\n // Perform initial health check\n this.performHealthCheck(pluginName, plugin, config).catch(error => {\n this.logger.error('Initial health check failed', { \n plugin: pluginName, \n error \n });\n });\n }\n\n /**\n * Stop monitoring a plugin\n */\n stopMonitoring(pluginName: string): void {\n const interval = this.checkIntervals.get(pluginName);\n if (interval) {\n clearInterval(interval);\n this.checkIntervals.delete(pluginName);\n this.logger.info('Health monitoring stopped', { plugin: pluginName });\n }\n }\n\n /**\n * Perform a health check on a plugin\n */\n private async performHealthCheck(\n pluginName: string,\n plugin: Plugin,\n config: PluginHealthCheck\n ): Promise<void> {\n const startTime = Date.now();\n let status: PluginHealthStatus = 'healthy';\n let message: string | undefined;\n const checks: Array<{ name: string; status: 'passed' | 'failed' | 'warning'; message?: string }> = [];\n\n try {\n // Check if plugin has a custom health check method\n if (config.checkMethod && typeof (plugin as any)[config.checkMethod] === 'function') {\n const checkResult = await Promise.race([\n (plugin as any)[config.checkMethod](),\n this.timeout(config.timeout, `Health check timeout after ${config.timeout}ms`)\n ]);\n\n if (checkResult === false || (checkResult && checkResult.status === 'unhealthy')) {\n status = 'unhealthy';\n message = checkResult?.message || 'Custom health check failed';\n checks.push({ name: config.checkMethod, status: 'failed', message });\n } else {\n checks.push({ name: config.checkMethod, status: 'passed' });\n }\n } else {\n // Default health check - just verify plugin is loaded\n checks.push({ name: 'plugin-loaded', status: 'passed' });\n }\n\n // Update counters based on result\n if (status === 'healthy') {\n this.successCounters.set(pluginName, (this.successCounters.get(pluginName) || 0) + 1);\n this.failureCounters.set(pluginName, 0);\n\n // Recover from unhealthy state if we have enough successes\n const currentStatus = this.healthStatus.get(pluginName);\n if (currentStatus === 'unhealthy' || currentStatus === 'degraded') {\n const successCount = this.successCounters.get(pluginName) || 0;\n if (successCount >= config.successThreshold) {\n this.healthStatus.set(pluginName, 'healthy');\n this.logger.info('Plugin recovered to healthy state', { plugin: pluginName });\n } else {\n this.healthStatus.set(pluginName, 'recovering');\n }\n } else {\n this.healthStatus.set(pluginName, 'healthy');\n }\n } else {\n this.failureCounters.set(pluginName, (this.failureCounters.get(pluginName) || 0) + 1);\n this.successCounters.set(pluginName, 0);\n\n const failureCount = this.failureCounters.get(pluginName) || 0;\n if (failureCount >= config.failureThreshold) {\n this.healthStatus.set(pluginName, 'unhealthy');\n this.logger.warn('Plugin marked as unhealthy', { \n plugin: pluginName, \n failures: failureCount \n });\n\n // Attempt auto-restart if configured\n if (config.autoRestart) {\n await this.attemptRestart(pluginName, plugin, config);\n }\n } else {\n this.healthStatus.set(pluginName, 'degraded');\n }\n }\n } catch (error) {\n status = 'failed';\n message = error instanceof Error ? error.message : 'Unknown error';\n this.failureCounters.set(pluginName, (this.failureCounters.get(pluginName) || 0) + 1);\n this.healthStatus.set(pluginName, 'failed');\n \n checks.push({ \n name: 'health-check', \n status: 'failed', \n message: message \n });\n\n this.logger.error('Health check exception', { \n plugin: pluginName, \n error \n });\n }\n\n // Create health report\n const report: PluginHealthReport = {\n status: this.healthStatus.get(pluginName) || 'unknown',\n timestamp: new Date().toISOString(),\n message,\n metrics: {\n uptime: Date.now() - startTime,\n },\n checks: checks.length > 0 ? checks : undefined,\n };\n\n this.healthReports.set(pluginName, report);\n }\n\n /**\n * Attempt to restart a plugin\n */\n private async attemptRestart(\n pluginName: string,\n plugin: Plugin,\n config: PluginHealthCheck\n ): Promise<void> {\n const attempts = this.restartAttempts.get(pluginName) || 0;\n \n if (attempts >= config.maxRestartAttempts) {\n this.logger.error('Max restart attempts reached, giving up', { \n plugin: pluginName, \n attempts \n });\n this.healthStatus.set(pluginName, 'failed');\n return;\n }\n\n this.restartAttempts.set(pluginName, attempts + 1);\n \n // Calculate backoff delay\n const delay = this.calculateBackoff(attempts, config.restartBackoff);\n \n this.logger.info('Scheduling plugin restart', { \n plugin: pluginName, \n attempt: attempts + 1, \n delay \n });\n\n await new Promise(resolve => setTimeout(resolve, delay));\n\n try {\n // Call destroy and init to restart\n if (plugin.destroy) {\n await plugin.destroy();\n }\n \n // Note: Full restart would require kernel context\n // This is a simplified version - actual implementation would need kernel integration\n this.logger.info('Plugin restarted', { plugin: pluginName });\n \n // Reset counters on successful restart\n this.failureCounters.set(pluginName, 0);\n this.successCounters.set(pluginName, 0);\n this.healthStatus.set(pluginName, 'recovering');\n } catch (error) {\n this.logger.error('Plugin restart failed', { \n plugin: pluginName, \n error \n });\n this.healthStatus.set(pluginName, 'failed');\n }\n }\n\n /**\n * Calculate backoff delay for restarts\n */\n private calculateBackoff(attempt: number, strategy: 'fixed' | 'linear' | 'exponential'): number {\n const baseDelay = 1000; // 1 second base\n\n switch (strategy) {\n case 'fixed':\n return baseDelay;\n case 'linear':\n return baseDelay * (attempt + 1);\n case 'exponential':\n return baseDelay * Math.pow(2, attempt);\n default:\n return baseDelay;\n }\n }\n\n /**\n * Get current health status of a plugin\n */\n getHealthStatus(pluginName: string): PluginHealthStatus | undefined {\n return this.healthStatus.get(pluginName);\n }\n\n /**\n * Get latest health report for a plugin\n */\n getHealthReport(pluginName: string): PluginHealthReport | undefined {\n return this.healthReports.get(pluginName);\n }\n\n /**\n * Get all health statuses\n */\n getAllHealthStatuses(): Map<string, PluginHealthStatus> {\n return new Map(this.healthStatus);\n }\n\n /**\n * Shutdown health monitor\n */\n shutdown(): void {\n // Stop all monitoring intervals\n for (const pluginName of this.checkIntervals.keys()) {\n this.stopMonitoring(pluginName);\n }\n \n this.healthChecks.clear();\n this.healthStatus.clear();\n this.healthReports.clear();\n this.failureCounters.clear();\n this.successCounters.clear();\n this.restartAttempts.clear();\n \n this.logger.info('Health monitor shutdown complete');\n }\n\n /**\n * Timeout helper\n */\n private timeout<T>(ms: number, message: string): Promise<T> {\n return new Promise((_, reject) => {\n setTimeout(() => reject(new Error(message)), ms);\n });\n }\n}\n","import type { \n HotReloadConfig, \n PluginStateSnapshot \n} from '@objectstack/spec/kernel';\nimport type { ObjectLogger } from './logger.js';\nimport type { Plugin } from './types.js';\n\n// Polyfill for UUID generation to support both Node.js and Browser\nconst generateUUID = () => {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n // Basic UUID v4 fallback\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {\n const r = Math.random() * 16 | 0;\n const v = c === 'x' ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n};\n\n/**\n * Plugin State Manager\n * \n * Handles state persistence and restoration during hot reloads\n */\nclass PluginStateManager {\n private logger: ObjectLogger;\n private stateSnapshots = new Map<string, PluginStateSnapshot>();\n private memoryStore = new Map<string, any>();\n\n constructor(logger: ObjectLogger) {\n this.logger = logger.child({ component: 'StateManager' });\n }\n\n /**\n * Save plugin state before reload\n */\n async saveState(\n pluginId: string,\n version: string,\n state: Record<string, any>,\n config: HotReloadConfig\n ): Promise<string> {\n const snapshot: PluginStateSnapshot = {\n pluginId,\n version,\n timestamp: new Date().toISOString(),\n state,\n metadata: {\n checksum: this.calculateChecksum(state),\n compressed: false,\n },\n };\n\n const snapshotId = generateUUID();\n\n switch (config.stateStrategy) {\n case 'memory':\n this.memoryStore.set(snapshotId, snapshot);\n this.logger.debug('State saved to memory', { pluginId, snapshotId });\n break;\n\n case 'disk':\n // For disk storage, we would write to file system\n // For now, store in memory as fallback\n this.memoryStore.set(snapshotId, snapshot);\n this.logger.debug('State saved to disk (memory fallback)', { pluginId, snapshotId });\n break;\n\n case 'distributed':\n // For distributed storage, would use Redis/etcd\n // For now, store in memory as fallback\n this.memoryStore.set(snapshotId, snapshot);\n this.logger.debug('State saved to distributed store (memory fallback)', { \n pluginId, \n snapshotId \n });\n break;\n\n case 'none':\n this.logger.debug('State persistence disabled', { pluginId });\n break;\n }\n\n this.stateSnapshots.set(pluginId, snapshot);\n return snapshotId;\n }\n\n /**\n * Restore plugin state after reload\n */\n async restoreState(\n pluginId: string,\n snapshotId?: string\n ): Promise<Record<string, any> | undefined> {\n // Try to get from snapshot ID first, otherwise use latest for plugin\n let snapshot: PluginStateSnapshot | undefined;\n\n if (snapshotId) {\n snapshot = this.memoryStore.get(snapshotId);\n } else {\n snapshot = this.stateSnapshots.get(pluginId);\n }\n\n if (!snapshot) {\n this.logger.warn('No state snapshot found', { pluginId, snapshotId });\n return undefined;\n }\n\n // Verify checksum if available\n if (snapshot.metadata?.checksum) {\n const currentChecksum = this.calculateChecksum(snapshot.state);\n if (currentChecksum !== snapshot.metadata.checksum) {\n this.logger.error('State checksum mismatch - data may be corrupted', { \n pluginId,\n expected: snapshot.metadata.checksum,\n actual: currentChecksum\n });\n return undefined;\n }\n }\n\n this.logger.debug('State restored', { pluginId, version: snapshot.version });\n return snapshot.state;\n }\n\n /**\n * Clear state for a plugin\n */\n clearState(pluginId: string): void {\n this.stateSnapshots.delete(pluginId);\n // Note: We don't clear memory store as it might have multiple snapshots\n this.logger.debug('State cleared', { pluginId });\n }\n\n /**\n * Calculate simple checksum for state verification\n * WARNING: This is a simple hash for demo purposes.\n * In production, use a cryptographic hash like SHA-256.\n */\n private calculateChecksum(state: Record<string, any>): string {\n // Simple checksum using JSON serialization\n // TODO: Replace with crypto.createHash('sha256') for production\n const stateStr = JSON.stringify(state);\n let hash = 0;\n for (let i = 0; i < stateStr.length; i++) {\n const char = stateStr.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n return hash.toString(16);\n }\n\n /**\n * Shutdown state manager\n */\n shutdown(): void {\n this.stateSnapshots.clear();\n this.memoryStore.clear();\n this.logger.info('State manager shutdown complete');\n }\n}\n\n/**\n * Hot Reload Manager\n * \n * Manages hot reloading of plugins with state preservation\n */\nexport class HotReloadManager {\n private logger: ObjectLogger;\n private stateManager: PluginStateManager;\n private reloadConfigs = new Map<string, HotReloadConfig>();\n private watchHandles = new Map<string, any>();\n private reloadTimers = new Map<string, NodeJS.Timeout>();\n\n constructor(logger: ObjectLogger) {\n this.logger = logger.child({ component: 'HotReload' });\n this.stateManager = new PluginStateManager(logger);\n }\n\n /**\n * Register a plugin for hot reload\n */\n registerPlugin(pluginName: string, config: HotReloadConfig): void {\n if (!config.enabled) {\n this.logger.debug('Hot reload disabled for plugin', { plugin: pluginName });\n return;\n }\n\n this.reloadConfigs.set(pluginName, config);\n this.logger.info('Plugin registered for hot reload', { \n plugin: pluginName,\n watchPatterns: config.watchPatterns,\n stateStrategy: config.stateStrategy\n });\n }\n\n /**\n * Start watching for changes (requires file system integration)\n */\n startWatching(pluginName: string): void {\n const config = this.reloadConfigs.get(pluginName);\n if (!config || !config.enabled) {\n return;\n }\n\n // Note: Actual file watching would require chokidar or similar\n // This is a placeholder for the integration point\n this.logger.info('File watching started', { \n plugin: pluginName,\n patterns: config.watchPatterns \n });\n }\n\n /**\n * Stop watching for changes\n */\n stopWatching(pluginName: string): void {\n const handle = this.watchHandles.get(pluginName);\n if (handle) {\n // Stop watching (would call chokidar close())\n this.watchHandles.delete(pluginName);\n this.logger.info('File watching stopped', { plugin: pluginName });\n }\n\n // Clear any pending reload timers\n const timer = this.reloadTimers.get(pluginName);\n if (timer) {\n clearTimeout(timer);\n this.reloadTimers.delete(pluginName);\n }\n }\n\n /**\n * Trigger hot reload for a plugin\n */\n async reloadPlugin(\n pluginName: string,\n plugin: Plugin,\n version: string,\n getPluginState: () => Record<string, any>,\n restorePluginState: (state: Record<string, any>) => void\n ): Promise<boolean> {\n const config = this.reloadConfigs.get(pluginName);\n if (!config) {\n this.logger.warn('Cannot reload - plugin not registered', { plugin: pluginName });\n return false;\n }\n\n this.logger.info('Starting hot reload', { plugin: pluginName });\n\n try {\n // Call before reload hooks\n if (config.beforeReload) {\n this.logger.debug('Executing before reload hooks', { \n plugin: pluginName,\n hooks: config.beforeReload \n });\n // Hook execution would be done through kernel's hook system\n }\n\n // Save state if configured\n let snapshotId: string | undefined;\n if (config.preserveState && config.stateStrategy !== 'none') {\n const state = getPluginState();\n snapshotId = await this.stateManager.saveState(\n pluginName,\n version,\n state,\n config\n );\n this.logger.debug('Plugin state saved', { plugin: pluginName, snapshotId });\n }\n\n // Gracefully shutdown the plugin\n if (plugin.destroy) {\n this.logger.debug('Destroying plugin', { plugin: pluginName });\n \n const shutdownPromise = plugin.destroy();\n const timeoutPromise = new Promise((_, reject) => {\n setTimeout(() => reject(new Error('Shutdown timeout')), config.shutdownTimeout);\n });\n\n await Promise.race([shutdownPromise, timeoutPromise]);\n this.logger.debug('Plugin destroyed successfully', { plugin: pluginName });\n }\n\n // At this point, the kernel would reload the plugin module\n // This would be handled by the plugin loader\n this.logger.debug('Plugin module would be reloaded here', { plugin: pluginName });\n\n // Restore state if we saved it\n if (snapshotId && config.preserveState) {\n const restoredState = await this.stateManager.restoreState(pluginName, snapshotId);\n if (restoredState) {\n restorePluginState(restoredState);\n this.logger.debug('Plugin state restored', { plugin: pluginName });\n }\n }\n\n // Call after reload hooks\n if (config.afterReload) {\n this.logger.debug('Executing after reload hooks', { \n plugin: pluginName,\n hooks: config.afterReload \n });\n // Hook execution would be done through kernel's hook system\n }\n\n this.logger.info('Hot reload completed successfully', { plugin: pluginName });\n return true;\n } catch (error) {\n this.logger.error('Hot reload failed', { \n plugin: pluginName, \n error \n });\n return false;\n }\n }\n\n /**\n * Schedule a reload with debouncing\n */\n scheduleReload(\n pluginName: string,\n reloadFn: () => Promise<void>\n ): void {\n const config = this.reloadConfigs.get(pluginName);\n if (!config) {\n return;\n }\n\n // Clear existing timer\n const existingTimer = this.reloadTimers.get(pluginName);\n if (existingTimer) {\n clearTimeout(existingTimer);\n }\n\n // Schedule new reload with debounce\n const timer = setTimeout(() => {\n this.logger.debug('Debounce period elapsed, executing reload', { \n plugin: pluginName \n });\n reloadFn().catch(error => {\n this.logger.error('Scheduled reload failed', { \n plugin: pluginName, \n error \n });\n });\n this.reloadTimers.delete(pluginName);\n }, config.debounceDelay);\n\n this.reloadTimers.set(pluginName, timer);\n this.logger.debug('Reload scheduled with debounce', { \n plugin: pluginName,\n delay: config.debounceDelay \n });\n }\n\n /**\n * Get state manager for direct access\n */\n getStateManager(): PluginStateManager {\n return this.stateManager;\n }\n\n /**\n * Shutdown hot reload manager\n */\n shutdown(): void {\n // Stop all watching\n for (const pluginName of this.watchHandles.keys()) {\n this.stopWatching(pluginName);\n }\n\n // Clear all timers\n for (const timer of this.reloadTimers.values()) {\n clearTimeout(timer);\n }\n\n this.reloadConfigs.clear();\n this.watchHandles.clear();\n this.reloadTimers.clear();\n this.stateManager.shutdown();\n \n this.logger.info('Hot reload manager shutdown complete');\n }\n}\n","import type { \n SemanticVersion,\n VersionConstraint,\n CompatibilityLevel,\n DependencyConflict\n} from '@objectstack/spec/kernel';\nimport type { ObjectLogger } from './logger.js';\n\n/**\n * Semantic Version Parser and Comparator\n * \n * Implements semantic versioning comparison and constraint matching\n */\nexport class SemanticVersionManager {\n /**\n * Parse a version string into semantic version components\n */\n static parse(versionStr: string): SemanticVersion {\n // Remove 'v' prefix if present\n const cleanVersion = versionStr.replace(/^v/, '');\n \n // Match semver pattern: major.minor.patch[-prerelease][+build]\n const match = cleanVersion.match(\n /^(\\d+)\\.(\\d+)\\.(\\d+)(?:-([a-zA-Z0-9.-]+))?(?:\\+([a-zA-Z0-9.-]+))?$/\n );\n\n if (!match) {\n throw new Error(`Invalid semantic version: ${versionStr}`);\n }\n\n return {\n major: parseInt(match[1], 10),\n minor: parseInt(match[2], 10),\n patch: parseInt(match[3], 10),\n preRelease: match[4],\n build: match[5],\n };\n }\n\n /**\n * Convert semantic version back to string\n */\n static toString(version: SemanticVersion): string {\n let str = `${version.major}.${version.minor}.${version.patch}`;\n if (version.preRelease) {\n str += `-${version.preRelease}`;\n }\n if (version.build) {\n str += `+${version.build}`;\n }\n return str;\n }\n\n /**\n * Compare two semantic versions\n * Returns: -1 if a < b, 0 if a === b, 1 if a > b\n */\n static compare(a: SemanticVersion, b: SemanticVersion): number {\n // Compare major, minor, patch\n if (a.major !== b.major) return a.major - b.major;\n if (a.minor !== b.minor) return a.minor - b.minor;\n if (a.patch !== b.patch) return a.patch - b.patch;\n\n // Pre-release versions have lower precedence\n if (a.preRelease && !b.preRelease) return -1;\n if (!a.preRelease && b.preRelease) return 1;\n \n // Compare pre-release versions\n if (a.preRelease && b.preRelease) {\n return a.preRelease.localeCompare(b.preRelease);\n }\n\n return 0;\n }\n\n /**\n * Check if version satisfies constraint\n */\n static satisfies(version: SemanticVersion, constraint: VersionConstraint): boolean {\n const constraintStr = constraint as string;\n\n // Any version\n if (constraintStr === '*' || constraintStr === 'latest') {\n return true;\n }\n\n // Exact version\n if (/^[\\d.]+$/.test(constraintStr)) {\n const exact = this.parse(constraintStr);\n return this.compare(version, exact) === 0;\n }\n\n // Caret range (^): Compatible with version\n if (constraintStr.startsWith('^')) {\n const base = this.parse(constraintStr.slice(1));\n return (\n version.major === base.major &&\n this.compare(version, base) >= 0\n );\n }\n\n // Tilde range (~): Approximately equivalent\n if (constraintStr.startsWith('~')) {\n const base = this.parse(constraintStr.slice(1));\n return (\n version.major === base.major &&\n version.minor === base.minor &&\n this.compare(version, base) >= 0\n );\n }\n\n // Greater than or equal\n if (constraintStr.startsWith('>=')) {\n const base = this.parse(constraintStr.slice(2));\n return this.compare(version, base) >= 0;\n }\n\n // Greater than\n if (constraintStr.startsWith('>')) {\n const base = this.parse(constraintStr.slice(1));\n return this.compare(version, base) > 0;\n }\n\n // Less than or equal\n if (constraintStr.startsWith('<=')) {\n const base = this.parse(constraintStr.slice(2));\n return this.compare(version, base) <= 0;\n }\n\n // Less than\n if (constraintStr.startsWith('<')) {\n const base = this.parse(constraintStr.slice(1));\n return this.compare(version, base) < 0;\n }\n\n // Range (1.2.3 - 2.3.4)\n const rangeMatch = constraintStr.match(/^([\\d.]+)\\s*-\\s*([\\d.]+)$/);\n if (rangeMatch) {\n const min = this.parse(rangeMatch[1]);\n const max = this.parse(rangeMatch[2]);\n return this.compare(version, min) >= 0 && this.compare(version, max) <= 0;\n }\n\n return false;\n }\n\n /**\n * Determine compatibility level between two versions\n */\n static getCompatibilityLevel(from: SemanticVersion, to: SemanticVersion): CompatibilityLevel {\n const cmp = this.compare(from, to);\n\n // Same version\n if (cmp === 0) {\n return 'fully-compatible';\n }\n\n // Major version changed - breaking changes\n if (from.major !== to.major) {\n return 'breaking-changes';\n }\n\n // Minor version increased - backward compatible\n if (from.minor < to.minor) {\n return 'backward-compatible';\n }\n\n // Patch version increased - fully compatible\n if (from.patch < to.patch) {\n return 'fully-compatible';\n }\n\n // Downgrade - incompatible\n return 'incompatible';\n }\n}\n\n/**\n * Plugin Dependency Resolver\n * \n * Resolves plugin dependencies using topological sorting and conflict detection\n */\nexport class DependencyResolver {\n private logger: ObjectLogger;\n\n constructor(logger: ObjectLogger) {\n this.logger = logger.child({ component: 'DependencyResolver' });\n }\n\n /**\n * Resolve dependencies using topological sort\n */\n resolve(\n plugins: Map<string, { version?: string; dependencies?: string[] }>\n ): string[] {\n const graph = new Map<string, string[]>();\n const inDegree = new Map<string, number>();\n\n // Build dependency graph\n for (const [pluginName, pluginInfo] of plugins) {\n if (!graph.has(pluginName)) {\n graph.set(pluginName, []);\n inDegree.set(pluginName, 0);\n }\n\n const deps = pluginInfo.dependencies || [];\n for (const dep of deps) {\n // Check if dependency exists\n if (!plugins.has(dep)) {\n throw new Error(`Missing dependency: ${pluginName} requires ${dep}`);\n }\n\n // Add edge\n if (!graph.has(dep)) {\n graph.set(dep, []);\n inDegree.set(dep, 0);\n }\n graph.get(dep)!.push(pluginName);\n inDegree.set(pluginName, (inDegree.get(pluginName) || 0) + 1);\n }\n }\n\n // Topological sort using Kahn's algorithm\n const queue: string[] = [];\n const result: string[] = [];\n\n // Add all nodes with no incoming edges\n for (const [node, degree] of inDegree) {\n if (degree === 0) {\n queue.push(node);\n }\n }\n\n while (queue.length > 0) {\n const node = queue.shift()!;\n result.push(node);\n\n // Reduce in-degree for dependent nodes\n const dependents = graph.get(node) || [];\n for (const dependent of dependents) {\n const newDegree = (inDegree.get(dependent) || 0) - 1;\n inDegree.set(dependent, newDegree);\n \n if (newDegree === 0) {\n queue.push(dependent);\n }\n }\n }\n\n // Check for circular dependencies\n if (result.length !== plugins.size) {\n const remaining = Array.from(plugins.keys()).filter(p => !result.includes(p));\n this.logger.error('Circular dependency detected', { remaining });\n throw new Error(`Circular dependency detected among: ${remaining.join(', ')}`);\n }\n\n this.logger.debug('Dependencies resolved', { order: result });\n return result;\n }\n\n /**\n * Detect dependency conflicts\n */\n detectConflicts(\n plugins: Map<string, { version: string; dependencies?: Record<string, VersionConstraint> }>\n ): DependencyConflict[] {\n const conflicts: DependencyConflict[] = [];\n const versionRequirements = new Map<string, Map<string, VersionConstraint>>();\n\n // Collect all version requirements\n for (const [pluginName, pluginInfo] of plugins) {\n if (!pluginInfo.dependencies) continue;\n\n for (const [depName, constraint] of Object.entries(pluginInfo.dependencies)) {\n if (!versionRequirements.has(depName)) {\n versionRequirements.set(depName, new Map());\n }\n versionRequirements.get(depName)!.set(pluginName, constraint);\n }\n }\n\n // Check for version mismatches\n for (const [depName, requirements] of versionRequirements) {\n const depInfo = plugins.get(depName);\n if (!depInfo) continue;\n\n const depVersion = SemanticVersionManager.parse(depInfo.version);\n const unsatisfied: Array<{ pluginId: string; version: string }> = [];\n\n for (const [requiringPlugin, constraint] of requirements) {\n if (!SemanticVersionManager.satisfies(depVersion, constraint)) {\n unsatisfied.push({\n pluginId: requiringPlugin,\n version: constraint as string,\n });\n }\n }\n\n if (unsatisfied.length > 0) {\n conflicts.push({\n type: 'version-mismatch',\n severity: 'error',\n description: `Version mismatch for ${depName}: detected ${unsatisfied.length} unsatisfied requirements`,\n plugins: [\n { pluginId: depName, version: depInfo.version },\n ...unsatisfied,\n ],\n resolutions: [{\n strategy: 'upgrade',\n description: `Upgrade ${depName} to satisfy all constraints`,\n targetPlugins: [depName],\n automatic: false,\n } as any],\n });\n }\n }\n\n // Check for circular dependencies (will be caught by resolve())\n try {\n this.resolve(new Map(\n Array.from(plugins.entries()).map(([name, info]) => [\n name,\n { version: info.version, dependencies: info.dependencies ? Object.keys(info.dependencies) : [] }\n ])\n ));\n } catch (error) {\n if (error instanceof Error && error.message.includes('Circular dependency')) {\n conflicts.push({\n type: 'circular-dependency',\n severity: 'critical',\n description: error.message,\n plugins: [], // Would need to extract from error\n resolutions: [{\n strategy: 'manual',\n description: 'Remove circular dependency by restructuring plugins',\n automatic: false,\n } as any],\n });\n }\n }\n\n return conflicts;\n }\n\n /**\n * Find best version that satisfies all constraints\n */\n findBestVersion(\n availableVersions: string[],\n constraints: VersionConstraint[]\n ): string | undefined {\n // Parse and sort versions (highest first)\n const versions = availableVersions\n .map(v => ({ str: v, parsed: SemanticVersionManager.parse(v) }))\n .sort((a, b) => -SemanticVersionManager.compare(a.parsed, b.parsed));\n\n // Find highest version that satisfies all constraints\n for (const version of versions) {\n const satisfiesAll = constraints.every(constraint =>\n SemanticVersionManager.satisfies(version.parsed, constraint)\n );\n\n if (satisfiesAll) {\n return version.str;\n }\n }\n\n return undefined;\n }\n\n /**\n * Check if dependencies form a valid DAG (no cycles)\n */\n isAcyclic(dependencies: Map<string, string[]>): boolean {\n try {\n const plugins = new Map(\n Array.from(dependencies.entries()).map(([name, deps]) => [\n name,\n { dependencies: deps }\n ])\n );\n this.resolve(plugins);\n return true;\n } catch {\n return false;\n }\n }\n}\n"],"mappings":"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","names":["ServiceLifecycle","service"]}
1
+ {"version":3,"sources":["../src/kernel-base.ts","../src/utils/env.ts","../src/logger.ts","../src/kernel.ts","../src/security/plugin-config-validator.ts","../src/plugin-loader.ts","../src/lite-kernel.ts","../src/api-registry.ts","../src/api-registry-plugin.ts","../src/qa/index.ts","../src/qa/runner.ts","../src/qa/http-adapter.ts","../src/security/plugin-signature-verifier.ts","../src/security/plugin-permission-enforcer.ts","../src/security/permission-manager.ts","../src/security/sandbox-runtime.ts","../src/security/security-scanner.ts","../src/health-monitor.ts","../src/hot-reload.ts","../src/dependency-resolver.ts"],"sourcesContent":["// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { Plugin, PluginContext } from './types.js';\nimport type { Logger } from '@objectstack/spec/contracts';\nimport type { IServiceRegistry } from '@objectstack/spec/contracts';\n\n/**\n * Kernel state machine\n */\nexport type KernelState = 'idle' | 'initializing' | 'running' | 'stopping' | 'stopped';\n\n/**\n * ObjectKernelBase - Abstract Base Class for Microkernel\n * \n * Provides common functionality for ObjectKernel and LiteKernel:\n * - Plugin management (Map storage)\n * - Dependency resolution (topological sort)\n * - Hook/Event system\n * - Context creation\n * - State validation\n * \n * This eliminates code duplication between the implementations.\n */\nexport abstract class ObjectKernelBase {\n protected plugins: Map<string, Plugin> = new Map();\n protected services: IServiceRegistry | Map<string, any> = new Map();\n protected hooks: Map<string, Array<(...args: any[]) => void | Promise<void>>> = new Map();\n protected state: KernelState = 'idle';\n protected logger: Logger;\n protected context!: PluginContext;\n\n constructor(logger: Logger) {\n this.logger = logger;\n }\n\n /**\n * Validate kernel state\n * @param requiredState - Required state for the operation\n * @throws Error if current state doesn't match\n */\n protected validateState(requiredState: KernelState): void {\n if (this.state !== requiredState) {\n throw new Error(\n `[Kernel] Invalid state: expected '${requiredState}', got '${this.state}'`\n );\n }\n }\n\n /**\n * Validate kernel is in idle state (for plugin registration)\n */\n protected validateIdle(): void {\n if (this.state !== 'idle') {\n throw new Error('[Kernel] Cannot register plugins after bootstrap has started');\n }\n }\n\n /**\n * Create the plugin context\n * Subclasses can override to customize context creation\n */\n protected createContext(): PluginContext {\n return {\n registerService: (name, service) => {\n if (this.services instanceof Map) {\n if (this.services.has(name)) {\n throw new Error(`[Kernel] Service '${name}' already registered`);\n }\n this.services.set(name, service);\n } else {\n // IServiceRegistry implementation\n this.services.register(name, service);\n }\n this.logger.info(`Service '${name}' registered`, { service: name });\n },\n getService: <T>(name: string): T => {\n if (this.services instanceof Map) {\n const service = this.services.get(name);\n if (!service) {\n throw new Error(`[Kernel] Service '${name}' not found`);\n }\n return service as T;\n } else {\n // IServiceRegistry implementation\n return this.services.get<T>(name);\n }\n },\n hook: (name, handler) => {\n if (!this.hooks.has(name)) {\n this.hooks.set(name, []);\n }\n this.hooks.get(name)!.push(handler);\n },\n trigger: async (name, ...args) => {\n const handlers = this.hooks.get(name) || [];\n for (const handler of handlers) {\n await handler(...args);\n }\n },\n getServices: () => {\n if (this.services instanceof Map) {\n return new Map(this.services);\n } else {\n // For IServiceRegistry, we need to return the underlying Map\n // This is a compatibility method\n return new Map();\n }\n },\n logger: this.logger,\n getKernel: () => this as any,\n };\n }\n\n /**\n * Resolve plugin dependencies using topological sort\n * @returns Ordered list of plugins (dependencies first)\n */\n protected resolveDependencies(): Plugin[] {\n const resolved: Plugin[] = [];\n const visited = new Set<string>();\n const visiting = new Set<string>();\n\n const visit = (pluginName: string) => {\n if (visited.has(pluginName)) return;\n \n if (visiting.has(pluginName)) {\n throw new Error(`[Kernel] Circular dependency detected: ${pluginName}`);\n }\n\n const plugin = this.plugins.get(pluginName);\n if (!plugin) {\n throw new Error(`[Kernel] Plugin '${pluginName}' not found`);\n }\n\n visiting.add(pluginName);\n\n // Visit dependencies first\n const deps = plugin.dependencies || [];\n for (const dep of deps) {\n if (!this.plugins.has(dep)) {\n throw new Error(\n `[Kernel] Dependency '${dep}' not found for plugin '${pluginName}'`\n );\n }\n visit(dep);\n }\n\n visiting.delete(pluginName);\n visited.add(pluginName);\n resolved.push(plugin);\n };\n\n // Visit all plugins\n for (const pluginName of this.plugins.keys()) {\n visit(pluginName);\n }\n\n return resolved;\n }\n\n /**\n * Run plugin init phase\n * @param plugin - Plugin to initialize\n */\n protected async runPluginInit(plugin: Plugin): Promise<void> {\n const pluginName = plugin.name;\n this.logger.info(`Initializing plugin: ${pluginName}`);\n \n try {\n await plugin.init(this.context);\n this.logger.info(`Plugin initialized: ${pluginName}`);\n } catch (error) {\n this.logger.error(`Plugin init failed: ${pluginName}`, error as Error);\n throw error;\n }\n }\n\n /**\n * Run plugin start phase\n * @param plugin - Plugin to start\n */\n protected async runPluginStart(plugin: Plugin): Promise<void> {\n if (!plugin.start) return;\n \n const pluginName = plugin.name;\n this.logger.info(`Starting plugin: ${pluginName}`);\n \n try {\n await plugin.start(this.context);\n this.logger.info(`Plugin started: ${pluginName}`);\n } catch (error) {\n this.logger.error(`Plugin start failed: ${pluginName}`, error as Error);\n throw error;\n }\n }\n\n /**\n * Run plugin destroy phase\n * @param plugin - Plugin to destroy\n */\n protected async runPluginDestroy(plugin: Plugin): Promise<void> {\n if (!plugin.destroy) return;\n \n const pluginName = plugin.name;\n this.logger.info(`Destroying plugin: ${pluginName}`);\n \n try {\n await plugin.destroy();\n this.logger.info(`Plugin destroyed: ${pluginName}`);\n } catch (error) {\n this.logger.error(`Plugin destroy failed: ${pluginName}`, error as Error);\n throw error;\n }\n }\n\n /**\n * Trigger a hook with all registered handlers\n * @param name - Hook name\n * @param args - Arguments to pass to handlers\n */\n protected async triggerHook(name: string, ...args: any[]): Promise<void> {\n const handlers = this.hooks.get(name) || [];\n this.logger.debug(`Triggering hook: ${name}`, { \n hook: name, \n handlerCount: handlers.length \n });\n \n for (const handler of handlers) {\n try {\n await handler(...args);\n } catch (error) {\n this.logger.error(`Hook handler failed: ${name}`, error as Error);\n // Continue with other handlers even if one fails\n }\n }\n }\n\n /**\n * Get current kernel state\n */\n getState(): KernelState {\n return this.state;\n }\n\n /**\n * Get all registered plugins\n */\n getPlugins(): Map<string, Plugin> {\n return new Map(this.plugins);\n }\n\n /**\n * Abstract methods to be implemented by subclasses\n */\n abstract use(plugin: Plugin): this | Promise<this>;\n abstract bootstrap(): Promise<void>;\n abstract destroy(): Promise<void>;\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * Environment utilities for universal (Node/Browser) compatibility.\n */\n\n// Check if running in a Node.js environment\nexport const isNode = typeof process !== 'undefined' && \n process.versions != null && \n process.versions.node != null;\n\n/**\n * Safely access environment variables\n */\nexport function getEnv(key: string, defaultValue?: string): string | undefined {\n // Node.js\n if (typeof process !== 'undefined' && process.env) {\n return process.env[key] || defaultValue;\n }\n \n // Browser (Vite/Webpack replacement usually handles process.env, \n // but if not, we check safe global access)\n try {\n // @ts-ignore\n if (typeof globalThis !== 'undefined' && globalThis.process?.env) {\n // @ts-ignore\n return globalThis.process.env[key] || defaultValue;\n }\n } catch (e) {\n // Ignore access errors\n }\n \n return defaultValue;\n}\n\n/**\n * Safely exit the process if in Node.js\n */\nexport function safeExit(code: number = 0): void {\n if (isNode) {\n process.exit(code);\n }\n}\n\n/**\n * Safely get memory usage\n */\nexport function getMemoryUsage(): { heapUsed: number; heapTotal: number } {\n if (isNode) {\n return process.memoryUsage();\n }\n return { heapUsed: 0, heapTotal: 0 };\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { LoggerConfig, LogLevel } from '@objectstack/spec/system';\nimport type { Logger } from '@objectstack/spec/contracts';\nimport { isNode } from './utils/env.js';\n\n/**\n * Universal Logger Implementation\n * \n * A configurable logger that works in both browser and Node.js environments.\n * - Node.js: Uses Pino for high-performance structured logging\n * - Browser: Simple console-based implementation\n * \n * Features:\n * - Structured logging with multiple formats (json, text, pretty)\n * - Log level filtering\n * - Sensitive data redaction\n * - File logging with rotation (Node.js only via Pino)\n * - Browser console integration\n * - Distributed tracing support (traceId, spanId)\n */\nexport class ObjectLogger implements Logger {\n private config: Required<Omit<LoggerConfig, 'file' | 'rotation' | 'name'>> & { file?: string; rotation?: { maxSize: string; maxFiles: number }; name?: string };\n private isNode: boolean;\n private pinoLogger?: any; // Pino logger instance for Node.js\n private pinoInstance?: any; // Base Pino instance for creating child loggers\n private require?: any; // CommonJS require function for Node.js\n\n constructor(config: Partial<LoggerConfig> = {}) {\n // Detect runtime environment\n this.isNode = isNode;\n\n // Set defaults\n this.config = {\n name: config.name,\n level: config.level ?? 'info',\n format: config.format ?? (this.isNode ? 'json' : 'pretty'),\n redact: config.redact ?? ['password', 'token', 'secret', 'key'],\n sourceLocation: config.sourceLocation ?? false,\n file: config.file,\n rotation: config.rotation ?? {\n maxSize: '10m',\n maxFiles: 5\n }\n };\n\n // Initialize Pino logger for Node.js\n if (this.isNode) {\n this.initPinoLogger();\n }\n }\n\n /**\n * Initialize Pino logger for Node.js\n */\n private async initPinoLogger() {\n if (!this.isNode) return;\n\n try {\n // Create require function dynamically for Node.js (avoids bundling issues in browser)\n // @ts-ignore - dynamic import of Node.js module\n const { createRequire } = await import('module');\n this.require = createRequire(import.meta.url);\n \n // Synchronous import for Pino using createRequire (works in ESM)\n const pino = this.require('pino');\n \n // Build Pino options\n const pinoOptions: any = {\n level: this.config.level,\n redact: {\n paths: this.config.redact,\n censor: '***REDACTED***'\n }\n };\n\n // Add name if provided\n if (this.config.name) {\n pinoOptions.name = this.config.name;\n }\n\n // Transport configuration for pretty printing or file output\n const targets: any[] = [];\n\n // Console transport\n if (this.config.format === 'pretty') {\n // Check if pino-pretty is available\n let hasPretty = false;\n try {\n this.require.resolve('pino-pretty');\n hasPretty = true;\n } catch (e) {\n // ignore\n }\n\n if (hasPretty) {\n targets.push({\n target: 'pino-pretty',\n options: {\n colorize: true,\n translateTime: 'SYS:standard',\n ignore: 'pid,hostname'\n },\n level: this.config.level\n });\n } else {\n console.warn('[Logger] pino-pretty not found. Install it for pretty logging: pnpm add -D pino-pretty');\n // Fallback to text/simple\n targets.push({\n target: 'pino/file',\n options: { destination: 1 },\n level: this.config.level\n });\n }\n } else if (this.config.format === 'json') {\n // JSON to stdout\n targets.push({\n target: 'pino/file',\n options: { destination: 1 }, // stdout\n level: this.config.level\n });\n } else {\n // text format (simple)\n targets.push({\n target: 'pino/file',\n options: { destination: 1 },\n level: this.config.level\n });\n }\n\n // File transport (if configured)\n if (this.config.file) {\n targets.push({\n target: 'pino/file',\n options: {\n destination: this.config.file,\n mkdir: true\n },\n level: this.config.level\n });\n }\n\n // Create transport\n if (targets.length > 0) {\n pinoOptions.transport = targets.length === 1 ? targets[0] : { targets };\n }\n\n // Create Pino logger\n this.pinoInstance = pino(pinoOptions);\n this.pinoLogger = this.pinoInstance;\n\n } catch (error) {\n // Fallback to console if Pino is not available\n console.warn('[Logger] Pino not available, falling back to console:', error);\n this.pinoLogger = null;\n }\n }\n\n /**\n * Redact sensitive keys from context object (for browser)\n */\n private redactSensitive(obj: any): any {\n if (!obj || typeof obj !== 'object') return obj;\n\n const redacted = Array.isArray(obj) ? [...obj] : { ...obj };\n\n for (const key in redacted) {\n const lowerKey = key.toLowerCase();\n const shouldRedact = this.config.redact.some((pattern: string) => \n lowerKey.includes(pattern.toLowerCase())\n );\n\n if (shouldRedact) {\n redacted[key] = '***REDACTED***';\n } else if (typeof redacted[key] === 'object' && redacted[key] !== null) {\n redacted[key] = this.redactSensitive(redacted[key]);\n }\n }\n\n return redacted;\n }\n\n /**\n * Format log entry for browser\n */\n private formatBrowserLog(level: LogLevel, message: string, context?: Record<string, any>): string {\n if (this.config.format === 'json') {\n return JSON.stringify({\n timestamp: new Date().toISOString(),\n level,\n message,\n ...context\n });\n }\n\n if (this.config.format === 'text') {\n const parts = [new Date().toISOString(), level.toUpperCase(), message];\n if (context && Object.keys(context).length > 0) {\n parts.push(JSON.stringify(context));\n }\n return parts.join(' | ');\n }\n\n // Pretty format\n const levelColors: Record<LogLevel, string> = {\n debug: '\\x1b[36m', // Cyan\n info: '\\x1b[32m', // Green\n warn: '\\x1b[33m', // Yellow\n error: '\\x1b[31m', // Red\n fatal: '\\x1b[35m', // Magenta\n silent: ''\n };\n const reset = '\\x1b[0m';\n const color = levelColors[level] || '';\n\n let output = `${color}[${level.toUpperCase()}]${reset} ${message}`;\n \n if (context && Object.keys(context).length > 0) {\n output += ` ${JSON.stringify(context, null, 2)}`;\n }\n\n return output;\n }\n\n /**\n * Log using browser console\n */\n private logBrowser(level: LogLevel, message: string, context?: Record<string, any>, error?: Error) {\n const redactedContext = context ? this.redactSensitive(context) : undefined;\n const mergedContext = error ? { ...redactedContext, error: { message: error.message, stack: error.stack } } : redactedContext;\n \n const formatted = this.formatBrowserLog(level, message, mergedContext);\n \n const consoleMethod = level === 'debug' ? 'debug' :\n level === 'info' ? 'log' :\n level === 'warn' ? 'warn' :\n level === 'error' || level === 'fatal' ? 'error' :\n 'log';\n \n console[consoleMethod](formatted);\n }\n\n /**\n * Public logging methods\n */\n debug(message: string, meta?: Record<string, any>): void {\n if (this.isNode && this.pinoLogger) {\n this.pinoLogger.debug(meta || {}, message);\n } else {\n this.logBrowser('debug', message, meta);\n }\n }\n\n info(message: string, meta?: Record<string, any>): void {\n if (this.isNode && this.pinoLogger) {\n this.pinoLogger.info(meta || {}, message);\n } else {\n this.logBrowser('info', message, meta);\n }\n }\n\n warn(message: string, meta?: Record<string, any>): void {\n if (this.isNode && this.pinoLogger) {\n this.pinoLogger.warn(meta || {}, message);\n } else {\n this.logBrowser('warn', message, meta);\n }\n }\n\n error(message: string, errorOrMeta?: Error | Record<string, any>, meta?: Record<string, any>): void {\n let error: Error | undefined;\n let context: Record<string, any> = {};\n\n if (errorOrMeta instanceof Error) {\n error = errorOrMeta;\n context = meta || {};\n } else {\n context = errorOrMeta || {};\n }\n\n if (this.isNode && this.pinoLogger) {\n const errorContext = error ? { err: error, ...context } : context;\n this.pinoLogger.error(errorContext, message);\n } else {\n this.logBrowser('error', message, context, error);\n }\n }\n\n fatal(message: string, errorOrMeta?: Error | Record<string, any>, meta?: Record<string, any>): void {\n let error: Error | undefined;\n let context: Record<string, any> = {};\n\n if (errorOrMeta instanceof Error) {\n error = errorOrMeta;\n context = meta || {};\n } else {\n context = errorOrMeta || {};\n }\n\n if (this.isNode && this.pinoLogger) {\n const errorContext = error ? { err: error, ...context } : context;\n this.pinoLogger.fatal(errorContext, message);\n } else {\n this.logBrowser('fatal', message, context, error);\n }\n }\n\n /**\n * Create a child logger with additional context\n * Note: Child loggers share the parent's Pino instance\n */\n child(context: Record<string, any>): ObjectLogger {\n const childLogger = new ObjectLogger(this.config);\n \n // For Node.js with Pino, create a Pino child logger\n if (this.isNode && this.pinoInstance) {\n childLogger.pinoLogger = this.pinoInstance.child(context);\n childLogger.pinoInstance = this.pinoInstance;\n }\n\n return childLogger;\n }\n\n /**\n * Set trace context for distributed tracing\n */\n withTrace(traceId: string, spanId?: string): ObjectLogger {\n return this.child({ traceId, spanId });\n }\n\n /**\n * Cleanup resources\n */\n async destroy(): Promise<void> {\n if (this.pinoLogger && this.pinoLogger.flush) {\n await new Promise<void>((resolve) => {\n this.pinoLogger.flush(() => resolve());\n });\n }\n }\n\n /**\n * Compatibility method for console.log usage\n */\n log(message: string, ...args: any[]): void {\n this.info(message, args.length > 0 ? { args } : undefined);\n }\n}\n\n/**\n * Create a logger instance\n */\nexport function createLogger(config?: Partial<LoggerConfig>): ObjectLogger {\n return new ObjectLogger(config);\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { Plugin, PluginContext } from './types.js';\nimport { createLogger, ObjectLogger } from './logger.js';\nimport type { LoggerConfig } from '@objectstack/spec/system';\nimport { ServiceRequirementDef } from '@objectstack/spec/system';\nimport { PluginLoader, PluginMetadata, ServiceLifecycle, ServiceFactory, PluginStartupResult } from './plugin-loader.js';\nimport { isNode, safeExit } from './utils/env.js';\n\n/**\n * Enhanced Kernel Configuration\n */\nexport interface ObjectKernelConfig {\n logger?: Partial<LoggerConfig>;\n \n /** Default plugin startup timeout in milliseconds */\n defaultStartupTimeout?: number;\n \n /** Whether to enable graceful shutdown */\n gracefulShutdown?: boolean;\n \n /** Graceful shutdown timeout in milliseconds */\n shutdownTimeout?: number;\n \n /** Whether to rollback on startup failure */\n rollbackOnFailure?: boolean;\n \n /** Whether to skip strict system requirement validation (Critical for testing) */\n skipSystemValidation?: boolean;\n}\n\n/**\n * Enhanced ObjectKernel with Advanced Plugin Management\n * \n * Extends the basic ObjectKernel with:\n * - Async plugin loading with validation\n * - Version compatibility checking\n * - Plugin signature verification\n * - Configuration validation (Zod)\n * - Factory-based dependency injection\n * - Service lifecycle management (singleton/transient/scoped)\n * - Circular dependency detection\n * - Lazy loading services\n * - Graceful shutdown\n * - Plugin startup timeout control\n * - Startup failure rollback\n * - Plugin health checks\n */\nexport class ObjectKernel {\n private plugins: Map<string, PluginMetadata> = new Map();\n private services: Map<string, any> = new Map();\n private hooks: Map<string, Array<(...args: any[]) => void | Promise<void>>> = new Map();\n private state: 'idle' | 'initializing' | 'running' | 'stopping' | 'stopped' = 'idle';\n private logger: ObjectLogger;\n private context: PluginContext;\n private pluginLoader: PluginLoader;\n private config: ObjectKernelConfig;\n private startedPlugins: Set<string> = new Set();\n private pluginStartTimes: Map<string, number> = new Map();\n private shutdownHandlers: Array<() => Promise<void>> = [];\n\n constructor(config: ObjectKernelConfig = {}) {\n this.config = {\n defaultStartupTimeout: 30000, // 30 seconds\n gracefulShutdown: true,\n shutdownTimeout: 60000, // 60 seconds\n rollbackOnFailure: true,\n ...config,\n };\n\n this.logger = createLogger(config.logger);\n this.pluginLoader = new PluginLoader(this.logger);\n \n // Initialize context\n this.context = {\n registerService: (name, service) => {\n this.registerService(name, service);\n },\n getService: <T>(name: string) => {\n // 1. Try direct service map first (synchronous cache)\n const service = this.services.get(name);\n if (service) {\n return service as T;\n }\n\n // 2. Try to get from plugin loader cache (Sync access to factories)\n const loaderService = this.pluginLoader.getServiceInstance<T>(name);\n if (loaderService) {\n // Cache it locally for faster next access\n this.services.set(name, loaderService);\n return loaderService;\n }\n\n // 3. Try to get from plugin loader (support async factories)\n try {\n const service = this.pluginLoader.getService(name);\n if (service instanceof Promise) {\n // If we found it in the loader but not in the sync map, it's likely a factory-based service or still loading\n // We must silence any potential rejection from this promise since we are about to throw our own error\n // and abandon the promise. Without this, Node.js will crash with \"Unhandled Promise Rejection\".\n service.catch(() => {});\n throw new Error(`Service '${name}' is async - use await`);\n }\n return service as T;\n } catch (error: any) {\n if (error.message?.includes('is async')) {\n throw error;\n }\n \n // Re-throw critical factory errors instead of masking them as \"not found\"\n // If the error came from the factory execution (e.g. database connection failed), we must see it.\n // \"Service '${name}' not found\" comes from PluginLoader.getService fallback.\n const isNotFoundError = error.message === `Service '${name}' not found`;\n \n if (!isNotFoundError) {\n throw error;\n }\n\n throw new Error(`[Kernel] Service '${name}' not found`);\n }\n },\n hook: (name, handler) => {\n if (!this.hooks.has(name)) {\n this.hooks.set(name, []);\n }\n this.hooks.get(name)!.push(handler);\n },\n trigger: async (name, ...args) => {\n const handlers = this.hooks.get(name) || [];\n for (const handler of handlers) {\n await handler(...args);\n }\n },\n getServices: () => {\n return new Map(this.services);\n },\n logger: this.logger,\n getKernel: () => this as any, // Type compatibility\n };\n\n this.pluginLoader.setContext(this.context);\n\n // Register shutdown handler\n if (this.config.gracefulShutdown) {\n this.registerShutdownSignals();\n }\n }\n\n /**\n * Register a plugin with enhanced validation\n */\n async use(plugin: Plugin): Promise<this> {\n if (this.state !== 'idle') {\n throw new Error('[Kernel] Cannot register plugins after bootstrap has started');\n }\n\n // Load plugin through enhanced loader\n const result = await this.pluginLoader.loadPlugin(plugin);\n \n if (!result.success || !result.plugin) {\n throw new Error(`Failed to load plugin: ${plugin.name} - ${result.error?.message}`);\n }\n\n const pluginMeta = result.plugin;\n this.plugins.set(pluginMeta.name, pluginMeta);\n \n this.logger.info(`Plugin registered: ${pluginMeta.name}@${pluginMeta.version}`, {\n plugin: pluginMeta.name,\n version: pluginMeta.version,\n });\n\n return this;\n }\n\n /**\n * Register a service instance directly\n */\n registerService<T>(name: string, service: T): this {\n if (this.services.has(name)) {\n throw new Error(`[Kernel] Service '${name}' already registered`);\n }\n this.services.set(name, service);\n this.pluginLoader.registerService(name, service);\n this.logger.info(`Service '${name}' registered`, { service: name });\n return this;\n }\n\n /**\n * Register a service factory with lifecycle management\n */\n registerServiceFactory<T>(\n name: string,\n factory: ServiceFactory<T>,\n lifecycle: ServiceLifecycle = ServiceLifecycle.SINGLETON,\n dependencies?: string[]\n ): this {\n this.pluginLoader.registerServiceFactory({\n name,\n factory,\n lifecycle,\n dependencies,\n });\n return this;\n }\n\n /**\n * Validate Critical System Requirements\n */\n private validateSystemRequirements() {\n if (this.config.skipSystemValidation) {\n this.logger.debug('System requirement validation skipped');\n return;\n }\n\n this.logger.debug('Validating system service requirements...');\n const missingServices: string[] = [];\n const missingCoreServices: string[] = [];\n \n // Iterate through all defined requirements\n for (const [serviceName, criticality] of Object.entries(ServiceRequirementDef)) {\n const hasService = this.services.has(serviceName) || this.pluginLoader.hasService(serviceName);\n \n if (!hasService) {\n if (criticality === 'required') {\n this.logger.error(`CRITICAL: Required service missing: ${serviceName}`);\n missingServices.push(serviceName);\n } else if (criticality === 'core') {\n this.logger.warn(`CORE: Core service missing, functionality may be degraded: ${serviceName}`);\n missingCoreServices.push(serviceName);\n } else {\n this.logger.info(`Info: Optional service not present: ${serviceName}`);\n }\n }\n }\n\n if (missingServices.length > 0) {\n const errorMsg = `System failed to start. Missing critical services: ${missingServices.join(', ')}`;\n this.logger.error(errorMsg);\n throw new Error(errorMsg);\n }\n\n if (missingCoreServices.length > 0) {\n this.logger.warn(`System started with degraded capabilities. Missing core services: ${missingCoreServices.join(', ')}`);\n }\n \n this.logger.info('System requirement check passed');\n }\n\n /**\n * Bootstrap the kernel with enhanced features\n */\n async bootstrap(): Promise<void> {\n if (this.state !== 'idle') {\n throw new Error('[Kernel] Kernel already bootstrapped');\n }\n\n this.state = 'initializing';\n this.logger.info('Bootstrap started');\n\n try {\n // Check for circular dependencies\n const cycles = this.pluginLoader.detectCircularDependencies();\n if (cycles.length > 0) {\n this.logger.warn('Circular service dependencies detected:', { cycles });\n }\n\n // Resolve plugin dependencies\n const orderedPlugins = this.resolveDependencies();\n\n // Phase 1: Init - Plugins register services\n this.logger.info('Phase 1: Init plugins');\n for (const plugin of orderedPlugins) {\n await this.initPluginWithTimeout(plugin);\n }\n\n // Phase 2: Start - Plugins execute business logic\n this.logger.info('Phase 2: Start plugins');\n this.state = 'running';\n \n for (const plugin of orderedPlugins) {\n const result = await this.startPluginWithTimeout(plugin);\n \n if (!result.success) {\n this.logger.error(`Plugin startup failed: ${plugin.name}`, result.error);\n \n if (this.config.rollbackOnFailure) {\n this.logger.warn('Rolling back started plugins...');\n await this.rollbackStartedPlugins();\n throw new Error(`Plugin ${plugin.name} failed to start - rollback complete`);\n }\n }\n }\n\n // Phase 3: Trigger kernel:ready hook\n this.validateSystemRequirements(); // Final check before ready\n this.logger.debug('Triggering kernel:ready hook');\n await this.context.trigger('kernel:ready');\n\n this.logger.info('✅ Bootstrap complete');\n } catch (error) {\n this.state = 'stopped';\n throw error;\n }\n }\n\n /**\n * Graceful shutdown with timeout\n */\n async shutdown(): Promise<void> {\n if (this.state === 'stopped' || this.state === 'stopping') {\n this.logger.warn('Kernel already stopped or stopping');\n return;\n }\n\n if (this.state !== 'running') {\n throw new Error('[Kernel] Kernel not running');\n }\n\n this.state = 'stopping';\n this.logger.info('Graceful shutdown started');\n\n try {\n // Create shutdown promise with timeout\n const shutdownPromise = this.performShutdown();\n const timeoutPromise = new Promise<void>((_, reject) => {\n setTimeout(() => {\n reject(new Error('Shutdown timeout exceeded'));\n }, this.config.shutdownTimeout);\n });\n\n // Race between shutdown and timeout\n await Promise.race([shutdownPromise, timeoutPromise]);\n\n this.state = 'stopped';\n this.logger.info('✅ Graceful shutdown complete');\n } catch (error) {\n this.logger.error('Shutdown error - forcing stop', error as Error);\n this.state = 'stopped';\n throw error;\n } finally {\n // Cleanup logger resources\n await this.logger.destroy();\n }\n }\n\n /**\n * Check health of a specific plugin\n */\n async checkPluginHealth(pluginName: string): Promise<any> {\n return await this.pluginLoader.checkPluginHealth(pluginName);\n }\n\n /**\n * Check health of all plugins\n */\n async checkAllPluginsHealth(): Promise<Map<string, any>> {\n const results = new Map();\n \n for (const pluginName of this.plugins.keys()) {\n const health = await this.checkPluginHealth(pluginName);\n results.set(pluginName, health);\n }\n \n return results;\n }\n\n /**\n * Get plugin startup metrics\n */\n getPluginMetrics(): Map<string, number> {\n return new Map(this.pluginStartTimes);\n }\n\n /**\n * Get a service (sync helper)\n */\n getService<T>(name: string): T {\n return this.context.getService<T>(name);\n }\n\n /**\n * Get a service asynchronously (supports factories)\n */\n async getServiceAsync<T>(name: string, scopeId?: string): Promise<T> {\n return await this.pluginLoader.getService<T>(name, scopeId);\n }\n\n /**\n * Check if kernel is running\n */\n isRunning(): boolean {\n return this.state === 'running';\n }\n\n /**\n * Get kernel state\n */\n getState(): string {\n return this.state;\n }\n\n // Private methods\n\n private async initPluginWithTimeout(plugin: PluginMetadata): Promise<void> {\n const timeout = plugin.startupTimeout || this.config.defaultStartupTimeout!;\n \n this.logger.debug(`Init: ${plugin.name}`, { plugin: plugin.name });\n \n const initPromise = plugin.init(this.context);\n const timeoutPromise = new Promise<void>((_, reject) => {\n setTimeout(() => {\n reject(new Error(`Plugin ${plugin.name} init timeout after ${timeout}ms`));\n }, timeout);\n });\n\n await Promise.race([initPromise, timeoutPromise]);\n }\n\n private async startPluginWithTimeout(plugin: PluginMetadata): Promise<PluginStartupResult> {\n if (!plugin.start) {\n return { success: true, pluginName: plugin.name };\n }\n\n const timeout = plugin.startupTimeout || this.config.defaultStartupTimeout!;\n const startTime = Date.now();\n \n this.logger.debug(`Start: ${plugin.name}`, { plugin: plugin.name });\n \n try {\n const startPromise = plugin.start(this.context);\n const timeoutPromise = new Promise<void>((_, reject) => {\n setTimeout(() => {\n reject(new Error(`Plugin ${plugin.name} start timeout after ${timeout}ms`));\n }, timeout);\n });\n\n await Promise.race([startPromise, timeoutPromise]);\n \n const duration = Date.now() - startTime;\n this.startedPlugins.add(plugin.name);\n this.pluginStartTimes.set(plugin.name, duration);\n \n this.logger.debug(`Plugin started: ${plugin.name} (${duration}ms)`);\n \n return {\n success: true,\n pluginName: plugin.name,\n startTime: duration,\n };\n } catch (error) {\n const duration = Date.now() - startTime;\n const isTimeout = (error as Error).message.includes('timeout');\n \n return {\n success: false,\n pluginName: plugin.name,\n error: error as Error,\n startTime: duration,\n timedOut: isTimeout,\n };\n }\n }\n\n private async rollbackStartedPlugins(): Promise<void> {\n const pluginsToRollback = Array.from(this.startedPlugins).reverse();\n \n for (const pluginName of pluginsToRollback) {\n const plugin = this.plugins.get(pluginName);\n if (plugin?.destroy) {\n try {\n this.logger.debug(`Rollback: ${pluginName}`);\n await plugin.destroy();\n } catch (error) {\n this.logger.error(`Rollback failed for ${pluginName}`, error as Error);\n }\n }\n }\n \n this.startedPlugins.clear();\n }\n\n private async performShutdown(): Promise<void> {\n // Trigger shutdown hook\n await this.context.trigger('kernel:shutdown');\n\n // Destroy plugins in reverse order\n const orderedPlugins = Array.from(this.plugins.values()).reverse();\n for (const plugin of orderedPlugins) {\n if (plugin.destroy) {\n this.logger.debug(`Destroy: ${plugin.name}`, { plugin: plugin.name });\n try {\n await plugin.destroy();\n } catch (error) {\n this.logger.error(`Error destroying plugin ${plugin.name}`, error as Error);\n }\n }\n }\n\n // Execute custom shutdown handlers\n for (const handler of this.shutdownHandlers) {\n try {\n await handler();\n } catch (error) {\n this.logger.error('Shutdown handler error', error as Error);\n }\n }\n }\n\n private resolveDependencies(): PluginMetadata[] {\n const resolved: PluginMetadata[] = [];\n const visited = new Set<string>();\n const visiting = new Set<string>();\n\n const visit = (pluginName: string) => {\n if (visited.has(pluginName)) return;\n \n if (visiting.has(pluginName)) {\n throw new Error(`[Kernel] Circular dependency detected: ${pluginName}`);\n }\n\n const plugin = this.plugins.get(pluginName);\n if (!plugin) {\n throw new Error(`[Kernel] Plugin '${pluginName}' not found`);\n }\n\n visiting.add(pluginName);\n\n // Visit dependencies first\n const deps = plugin.dependencies || [];\n for (const dep of deps) {\n if (!this.plugins.has(dep)) {\n throw new Error(`[Kernel] Dependency '${dep}' not found for plugin '${pluginName}'`);\n }\n visit(dep);\n }\n\n visiting.delete(pluginName);\n visited.add(pluginName);\n resolved.push(plugin);\n };\n\n // Visit all plugins\n for (const pluginName of this.plugins.keys()) {\n visit(pluginName);\n }\n\n return resolved;\n }\n\n private registerShutdownSignals(): void {\n const signals: NodeJS.Signals[] = ['SIGINT', 'SIGTERM', 'SIGQUIT'];\n let shutdownInProgress = false;\n \n const handleShutdown = async (signal: string) => {\n if (shutdownInProgress) {\n this.logger.warn(`Shutdown already in progress, ignoring ${signal}`);\n return;\n }\n \n shutdownInProgress = true;\n this.logger.info(`Received ${signal} - initiating graceful shutdown`);\n \n try {\n await this.shutdown();\n safeExit(0);\n } catch (error) {\n this.logger.error('Shutdown failed', error as Error);\n safeExit(1);\n }\n };\n \n if (isNode) {\n for (const signal of signals) {\n process.on(signal, () => handleShutdown(signal));\n }\n }\n }\n\n /**\n * Register a custom shutdown handler\n */\n onShutdown(handler: () => Promise<void>): void {\n this.shutdownHandlers.push(handler);\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { z } from 'zod';\nimport type { Logger } from '@objectstack/spec/contracts';\nimport type { PluginMetadata } from '../plugin-loader.js';\n\n/**\n * Plugin Configuration Validator\n * \n * Validates plugin configurations against Zod schemas to ensure:\n * 1. Type safety - all config values have correct types\n * 2. Business rules - values meet constraints (min/max, regex, etc.)\n * 3. Required fields - all mandatory configuration is provided\n * 4. Default values - missing optional fields get defaults\n * \n * Architecture:\n * - Uses Zod for runtime validation\n * - Provides detailed error messages with field paths\n * - Supports nested configuration objects\n * - Allows partial validation for incremental updates\n * \n * Usage:\n * ```typescript\n * const validator = new PluginConfigValidator(logger);\n * const validConfig = validator.validatePluginConfig(plugin, userConfig);\n * ```\n */\nexport class PluginConfigValidator {\n private logger: Logger;\n \n constructor(logger: Logger) {\n this.logger = logger;\n }\n \n /**\n * Validate plugin configuration against its Zod schema\n * \n * @param plugin - Plugin metadata with configSchema\n * @param config - User-provided configuration\n * @returns Validated and typed configuration\n * @throws Error with detailed validation errors\n */\n validatePluginConfig<T = any>(plugin: PluginMetadata, config: any): T {\n if (!plugin.configSchema) {\n this.logger.debug(`Plugin ${plugin.name} has no config schema - skipping validation`);\n return config as T;\n }\n \n try {\n // Use Zod to parse and validate\n const validatedConfig = plugin.configSchema.parse(config);\n \n this.logger.debug(`✅ Plugin config validated: ${plugin.name}`, {\n plugin: plugin.name,\n configKeys: Object.keys(config || {}).length,\n });\n \n return validatedConfig as T;\n } catch (error) {\n if (error instanceof z.ZodError) {\n const formattedErrors = this.formatZodErrors(error);\n const errorMessage = [\n `Plugin ${plugin.name} configuration validation failed:`,\n ...formattedErrors.map(e => ` - ${e.path}: ${e.message}`),\n ].join('\\n');\n \n this.logger.error(errorMessage, undefined, {\n plugin: plugin.name,\n errors: formattedErrors,\n });\n \n throw new Error(errorMessage);\n }\n \n // Re-throw other errors\n throw error;\n }\n }\n \n /**\n * Validate partial configuration (for incremental updates)\n * \n * @param plugin - Plugin metadata\n * @param partialConfig - Partial configuration to validate\n * @returns Validated partial configuration\n */\n validatePartialConfig<T = any>(plugin: PluginMetadata, partialConfig: any): Partial<T> {\n if (!plugin.configSchema) {\n return partialConfig as Partial<T>;\n }\n \n try {\n // Use Zod's partial() method for partial validation\n // Cast to ZodObject to access partial() method\n const partialSchema = (plugin.configSchema as any).partial();\n const validatedConfig = partialSchema.parse(partialConfig);\n \n this.logger.debug(`✅ Partial config validated: ${plugin.name}`);\n return validatedConfig as Partial<T>;\n } catch (error) {\n if (error instanceof z.ZodError) {\n const formattedErrors = this.formatZodErrors(error);\n const errorMessage = [\n `Plugin ${plugin.name} partial configuration validation failed:`,\n ...formattedErrors.map(e => ` - ${e.path}: ${e.message}`),\n ].join('\\n');\n \n throw new Error(errorMessage);\n }\n \n throw error;\n }\n }\n \n /**\n * Get default configuration from schema\n * \n * @param plugin - Plugin metadata\n * @returns Default configuration object\n */\n getDefaultConfig<T = any>(plugin: PluginMetadata): T | undefined {\n if (!plugin.configSchema) {\n return undefined;\n }\n \n try {\n // Parse empty object to get defaults\n const defaults = plugin.configSchema.parse({});\n this.logger.debug(`Default config extracted: ${plugin.name}`);\n return defaults as T;\n } catch (error) {\n // Schema may require some fields - return undefined\n this.logger.debug(`No default config available: ${plugin.name}`);\n return undefined;\n }\n }\n \n /**\n * Check if configuration is valid without throwing\n * \n * @param plugin - Plugin metadata\n * @param config - Configuration to check\n * @returns True if valid, false otherwise\n */\n isConfigValid(plugin: PluginMetadata, config: any): boolean {\n if (!plugin.configSchema) {\n return true;\n }\n \n const result = plugin.configSchema.safeParse(config);\n return result.success;\n }\n \n /**\n * Get configuration errors without throwing\n * \n * @param plugin - Plugin metadata\n * @param config - Configuration to check\n * @returns Array of validation errors, or empty array if valid\n */\n getConfigErrors(plugin: PluginMetadata, config: any): Array<{path: string; message: string}> {\n if (!plugin.configSchema) {\n return [];\n }\n \n const result = plugin.configSchema.safeParse(config);\n \n if (result.success) {\n return [];\n }\n \n return this.formatZodErrors(result.error);\n }\n \n // Private methods\n \n private formatZodErrors(error: z.ZodError<any>): Array<{path: string; message: string}> {\n return error.issues.map((e: z.ZodIssue) => ({\n path: e.path.join('.') || 'root',\n message: e.message,\n }));\n }\n}\n\n/**\n * Create a plugin config validator\n * \n * @param logger - Logger instance\n * @returns Plugin config validator\n */\nexport function createPluginConfigValidator(logger: Logger): PluginConfigValidator {\n return new PluginConfigValidator(logger);\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { Plugin, PluginContext } from './types.js';\nimport type { Logger } from '@objectstack/spec/contracts';\nimport { z } from 'zod';\nimport { PluginConfigValidator } from './security/plugin-config-validator.js';\n\n/**\n * Service Lifecycle Types\n * Defines how services are instantiated and managed\n */\nexport enum ServiceLifecycle {\n /** Single instance shared across all requests */\n SINGLETON = 'singleton',\n /** New instance created for each request */\n TRANSIENT = 'transient',\n /** New instance per scope (e.g., per HTTP request) */\n SCOPED = 'scoped',\n}\n\n/**\n * Service Factory\n * Function that creates a service instance\n */\nexport type ServiceFactory<T = any> = (ctx: PluginContext) => T | Promise<T>;\n\n/**\n * Service Registration Options\n */\nexport interface ServiceRegistration {\n name: string;\n factory: ServiceFactory;\n lifecycle: ServiceLifecycle;\n dependencies?: string[];\n}\n\n/**\n * Plugin Configuration Validator Interface\n * Uses Zod for runtime validation of plugin configurations\n * @deprecated Use the PluginConfigValidator class from security module instead\n */\nexport interface IPluginConfigValidator {\n schema: z.ZodSchema;\n validate(config: any): any;\n}\n\n/**\n * Plugin Metadata with Enhanced Features\n */\nexport interface PluginMetadata extends Plugin {\n /** Semantic version (e.g., \"1.0.0\") */\n version: string;\n \n /** Configuration schema for validation */\n configSchema?: z.ZodSchema;\n \n /** Plugin signature for security verification */\n signature?: string;\n \n /** Plugin health check function */\n healthCheck?(): Promise<PluginHealthStatus>;\n \n /** Startup timeout in milliseconds (default: 30000) */\n startupTimeout?: number;\n \n /** Whether plugin supports hot reload */\n hotReloadable?: boolean;\n}\n\n/**\n * Plugin Health Status\n */\nexport interface PluginHealthStatus {\n healthy: boolean;\n message?: string;\n details?: Record<string, any>;\n lastCheck?: Date;\n}\n\n/**\n * Plugin Load Result\n */\nexport interface PluginLoadResult {\n success: boolean;\n plugin?: PluginMetadata;\n error?: Error;\n loadTime?: number;\n}\n\n/**\n * Plugin Startup Result\n */\nexport interface PluginStartupResult {\n success: boolean;\n pluginName: string;\n startTime?: number;\n error?: Error;\n timedOut?: boolean;\n}\n\n/**\n * Version Compatibility Result\n */\nexport interface VersionCompatibility {\n compatible: boolean;\n pluginVersion: string;\n requiredVersion?: string;\n message?: string;\n}\n\n/**\n * Enhanced Plugin Loader\n * Provides advanced plugin loading capabilities with validation, security, and lifecycle management\n */\nexport class PluginLoader {\n private logger: Logger;\n private context?: PluginContext;\n private configValidator: PluginConfigValidator;\n private loadedPlugins: Map<string, PluginMetadata> = new Map();\n private serviceFactories: Map<string, ServiceRegistration> = new Map();\n private serviceInstances: Map<string, any> = new Map();\n private scopedServices: Map<string, Map<string, any>> = new Map();\n private creating: Set<string> = new Set();\n\n constructor(logger: Logger) {\n this.logger = logger;\n this.configValidator = new PluginConfigValidator(logger);\n }\n\n /**\n * Set the plugin context for service factories\n */\n setContext(context: PluginContext): void {\n this.context = context;\n }\n\n /**\n * Get a synchronous service instance if it exists (Sync Helper)\n */\n getServiceInstance<T>(name: string): T | undefined {\n return this.serviceInstances.get(name) as T;\n }\n\n /**\n * Load a plugin asynchronously with validation\n */\n async loadPlugin(plugin: Plugin): Promise<PluginLoadResult> {\n const startTime = Date.now();\n \n try {\n this.logger.info(`Loading plugin: ${plugin.name}`);\n \n // Convert to PluginMetadata\n const metadata = this.toPluginMetadata(plugin);\n \n // Validate plugin structure\n this.validatePluginStructure(metadata);\n \n // Check version compatibility\n const versionCheck = this.checkVersionCompatibility(metadata);\n if (!versionCheck.compatible) {\n throw new Error(`Version incompatible: ${versionCheck.message}`);\n }\n \n // Validate configuration if schema is provided\n if (metadata.configSchema) {\n this.validatePluginConfig(metadata);\n }\n \n // Verify signature if provided\n if (metadata.signature) {\n await this.verifyPluginSignature(metadata);\n }\n \n // Store loaded plugin\n this.loadedPlugins.set(metadata.name, metadata);\n \n const loadTime = Date.now() - startTime;\n this.logger.info(`Plugin loaded: ${plugin.name} (${loadTime}ms)`);\n \n return {\n success: true,\n plugin: metadata,\n loadTime,\n };\n } catch (error) {\n this.logger.error(`Failed to load plugin: ${plugin.name}`, error as Error);\n return {\n success: false,\n error: error as Error,\n loadTime: Date.now() - startTime,\n };\n }\n }\n\n /**\n * Register a service with factory function\n */\n registerServiceFactory(registration: ServiceRegistration): void {\n if (this.serviceFactories.has(registration.name)) {\n throw new Error(`Service factory '${registration.name}' already registered`);\n }\n \n this.serviceFactories.set(registration.name, registration);\n this.logger.debug(`Service factory registered: ${registration.name} (${registration.lifecycle})`);\n }\n\n /**\n * Get or create a service instance based on lifecycle type\n */\n async getService<T>(name: string, scopeId?: string): Promise<T> {\n const registration = this.serviceFactories.get(name);\n \n if (!registration) {\n // Fall back to static service instances\n const instance = this.serviceInstances.get(name);\n if (!instance) {\n throw new Error(`Service '${name}' not found`);\n }\n return instance as T;\n }\n \n switch (registration.lifecycle) {\n case ServiceLifecycle.SINGLETON:\n return await this.getSingletonService<T>(registration);\n \n case ServiceLifecycle.TRANSIENT:\n return await this.createTransientService<T>(registration);\n \n case ServiceLifecycle.SCOPED:\n if (!scopeId) {\n throw new Error(`Scope ID required for scoped service '${name}'`);\n }\n return await this.getScopedService<T>(registration, scopeId);\n \n default:\n throw new Error(`Unknown service lifecycle: ${registration.lifecycle}`);\n }\n }\n\n /**\n * Register a static service instance (legacy support)\n */\n registerService(name: string, service: any): void {\n if (this.serviceInstances.has(name)) {\n throw new Error(`Service '${name}' already registered`);\n }\n this.serviceInstances.set(name, service);\n }\n\n /**\n * Check if a service is registered (either as instance or factory)\n */\n hasService(name: string): boolean {\n return this.serviceInstances.has(name) || this.serviceFactories.has(name);\n }\n\n /**\n * Detect circular dependencies in service factories\n * Note: This only detects cycles in service dependencies, not plugin dependencies.\n * Plugin dependency cycles are detected in the kernel's resolveDependencies method.\n */\n detectCircularDependencies(): string[] {\n const cycles: string[] = [];\n const visited = new Set<string>();\n const visiting = new Set<string>();\n \n const visit = (serviceName: string, path: string[] = []) => {\n if (visiting.has(serviceName)) {\n const cycle = [...path, serviceName].join(' -> ');\n cycles.push(cycle);\n return;\n }\n \n if (visited.has(serviceName)) {\n return;\n }\n \n visiting.add(serviceName);\n \n const registration = this.serviceFactories.get(serviceName);\n if (registration?.dependencies) {\n for (const dep of registration.dependencies) {\n visit(dep, [...path, serviceName]);\n }\n }\n \n visiting.delete(serviceName);\n visited.add(serviceName);\n };\n \n for (const serviceName of this.serviceFactories.keys()) {\n visit(serviceName);\n }\n \n return cycles;\n }\n\n /**\n * Check plugin health\n */\n async checkPluginHealth(pluginName: string): Promise<PluginHealthStatus> {\n const plugin = this.loadedPlugins.get(pluginName);\n \n if (!plugin) {\n return {\n healthy: false,\n message: 'Plugin not found',\n lastCheck: new Date(),\n };\n }\n \n if (!plugin.healthCheck) {\n return {\n healthy: true,\n message: 'No health check defined',\n lastCheck: new Date(),\n };\n }\n \n try {\n const status = await plugin.healthCheck();\n return {\n ...status,\n lastCheck: new Date(),\n };\n } catch (error) {\n return {\n healthy: false,\n message: `Health check failed: ${(error as Error).message}`,\n lastCheck: new Date(),\n };\n }\n }\n\n /**\n * Clear scoped services for a scope\n */\n clearScope(scopeId: string): void {\n this.scopedServices.delete(scopeId);\n this.logger.debug(`Cleared scope: ${scopeId}`);\n }\n\n /**\n * Get all loaded plugins\n */\n getLoadedPlugins(): Map<string, PluginMetadata> {\n return new Map(this.loadedPlugins);\n }\n\n // Private helper methods\n\n private toPluginMetadata(plugin: Plugin): PluginMetadata {\n // Fix: Do not use object spread {...plugin} as it destroys the prototype chain for Class-based plugins.\n // Instead, cast the original object and inject default values if missing.\n const metadata = plugin as PluginMetadata;\n \n if (!metadata.version) {\n metadata.version = '0.0.0';\n }\n \n return metadata;\n }\n\n private validatePluginStructure(plugin: PluginMetadata): void {\n if (!plugin.name) {\n throw new Error('Plugin name is required');\n }\n \n if (!plugin.init) {\n throw new Error('Plugin init function is required');\n }\n \n if (!this.isValidSemanticVersion(plugin.version)) {\n throw new Error(`Invalid semantic version: ${plugin.version}`);\n }\n }\n\n private checkVersionCompatibility(plugin: PluginMetadata): VersionCompatibility {\n // Basic semantic version compatibility check\n // In a real implementation, this would check against kernel version\n const version = plugin.version;\n \n if (!this.isValidSemanticVersion(version)) {\n return {\n compatible: false,\n pluginVersion: version,\n message: 'Invalid semantic version format',\n };\n }\n \n return {\n compatible: true,\n pluginVersion: version,\n };\n }\n\n private isValidSemanticVersion(version: string): boolean {\n const semverRegex = /^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?(\\+[a-zA-Z0-9.-]+)?$/;\n return semverRegex.test(version);\n }\n\n private validatePluginConfig(plugin: PluginMetadata, config?: any): void {\n if (!plugin.configSchema) {\n return;\n }\n\n if (config === undefined) {\n // In loadPlugin, we often don't have the config yet.\n // We skip validation here or valid against empty object if schema allows?\n // For now, let's keep the logging behavior but note it's delegating\n this.logger.debug(`Plugin ${plugin.name} has configuration schema (config validation postponed)`);\n return;\n }\n\n this.configValidator.validatePluginConfig(plugin, config);\n }\n\n private async verifyPluginSignature(plugin: PluginMetadata): Promise<void> {\n if (!plugin.signature) {\n return;\n }\n \n // Plugin signature verification is now implemented in PluginSignatureVerifier\n // This is a placeholder that logs the verification would happen\n // The actual verification should be done by the caller with proper security config\n this.logger.debug(`Plugin ${plugin.name} has signature (use PluginSignatureVerifier for verification)`);\n }\n\n private async getSingletonService<T>(registration: ServiceRegistration): Promise<T> {\n let instance = this.serviceInstances.get(registration.name);\n \n if (!instance) {\n // Create instance (would need context)\n instance = await this.createServiceInstance(registration);\n this.serviceInstances.set(registration.name, instance);\n this.logger.debug(`Singleton service created: ${registration.name}`);\n }\n \n return instance as T;\n }\n\n private async createTransientService<T>(registration: ServiceRegistration): Promise<T> {\n const instance = await this.createServiceInstance(registration);\n this.logger.debug(`Transient service created: ${registration.name}`);\n return instance as T;\n }\n\n private async getScopedService<T>(registration: ServiceRegistration, scopeId: string): Promise<T> {\n if (!this.scopedServices.has(scopeId)) {\n this.scopedServices.set(scopeId, new Map());\n }\n \n const scope = this.scopedServices.get(scopeId)!;\n let instance = scope.get(registration.name);\n \n if (!instance) {\n instance = await this.createServiceInstance(registration);\n scope.set(registration.name, instance);\n this.logger.debug(`Scoped service created: ${registration.name} (scope: ${scopeId})`);\n }\n \n return instance as T;\n }\n\n private async createServiceInstance(registration: ServiceRegistration): Promise<any> {\n if (!this.context) {\n throw new Error(`[PluginLoader] Context not set - cannot create service '${registration.name}'`);\n }\n\n if (this.creating.has(registration.name)) {\n throw new Error(`Circular dependency detected: ${Array.from(this.creating).join(' -> ')} -> ${registration.name}`);\n }\n\n this.creating.add(registration.name);\n try {\n return await registration.factory(this.context);\n } finally {\n this.creating.delete(registration.name);\n }\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { Plugin } from './types.js';\nimport { createLogger, ObjectLogger } from './logger.js';\nimport type { LoggerConfig } from '@objectstack/spec/system';\nimport { ObjectKernelBase } from './kernel-base.js';\n\n/**\n * ObjectKernel - MiniKernel Architecture\n * \n * A highly modular, plugin-based microkernel that:\n * - Manages plugin lifecycle (init, start, destroy)\n * - Provides dependency injection via service registry\n * - Implements event/hook system for inter-plugin communication\n * - Handles dependency resolution (topological sort)\n * - Provides configurable logging for server and browser\n * \n * Core philosophy:\n * - Business logic is completely separated into plugins\n * - Kernel only manages lifecycle, DI, and hooks\n * - Plugins are loaded as equal building blocks\n */\nexport class LiteKernel extends ObjectKernelBase {\n constructor(config?: { logger?: Partial<LoggerConfig> }) {\n const logger = createLogger(config?.logger);\n super(logger);\n \n // Initialize context after logger is created\n this.context = this.createContext();\n }\n\n /**\n * Register a plugin\n * @param plugin - Plugin instance\n */\n use(plugin: Plugin): this {\n this.validateIdle();\n\n const pluginName = plugin.name;\n if (this.plugins.has(pluginName)) {\n throw new Error(`[Kernel] Plugin '${pluginName}' already registered`);\n }\n\n this.plugins.set(pluginName, plugin);\n return this;\n }\n\n /**\n * Bootstrap the kernel\n * 1. Resolve dependencies (topological sort)\n * 2. Init phase - plugins register services\n * 3. Start phase - plugins execute business logic\n * 4. Trigger 'kernel:ready' hook\n */\n async bootstrap(): Promise<void> {\n this.validateState('idle');\n\n this.state = 'initializing';\n this.logger.info('Bootstrap started');\n\n // Resolve dependencies\n const orderedPlugins = this.resolveDependencies();\n\n // Phase 1: Init - Plugins register services\n this.logger.info('Phase 1: Init plugins');\n for (const plugin of orderedPlugins) {\n await this.runPluginInit(plugin);\n }\n\n // Phase 2: Start - Plugins execute business logic\n this.logger.info('Phase 2: Start plugins');\n this.state = 'running';\n \n for (const plugin of orderedPlugins) {\n await this.runPluginStart(plugin);\n }\n\n // Trigger ready hook\n await this.triggerHook('kernel:ready');\n this.logger.info('✅ Bootstrap complete', { \n pluginCount: this.plugins.size \n });\n }\n\n /**\n * Shutdown the kernel\n * Calls destroy on all plugins in reverse order\n */\n async shutdown(): Promise<void> {\n await this.destroy();\n }\n\n /**\n * Graceful shutdown - destroy all plugins in reverse order\n */\n async destroy(): Promise<void> {\n if (this.state === 'stopped') {\n this.logger.warn('Kernel already stopped');\n return;\n }\n\n this.state = 'stopping';\n this.logger.info('Shutdown started');\n\n // Trigger shutdown hook\n await this.triggerHook('kernel:shutdown');\n\n // Destroy plugins in reverse order\n const orderedPlugins = this.resolveDependencies();\n for (const plugin of orderedPlugins.reverse()) {\n await this.runPluginDestroy(plugin);\n }\n\n this.state = 'stopped';\n this.logger.info('✅ Shutdown complete');\n \n // Cleanup logger resources\n if (this.logger && typeof (this.logger as ObjectLogger).destroy === 'function') {\n await (this.logger as ObjectLogger).destroy();\n }\n }\n\n /**\n * Get a service from the registry\n * Convenience method for external access\n */\n getService<T>(name: string): T {\n return this.context.getService<T>(name);\n }\n\n /**\n * Check if kernel is running\n */\n isRunning(): boolean {\n return this.state === 'running';\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type {\n ApiRegistry as ApiRegistryType,\n ApiRegistryEntry,\n ApiRegistryEntryInput,\n ApiEndpointRegistration,\n ConflictResolutionStrategy,\n ApiDiscoveryQuery,\n ApiDiscoveryResponse,\n} from '@objectstack/spec/api';\nimport { ApiRegistryEntrySchema } from '@objectstack/spec/api';\nimport type { Logger } from '@objectstack/spec/contracts';\nimport { getEnv } from './utils/env.js';\n\n/**\n * API Registry Service\n * \n * Central registry for managing API endpoints across different protocols.\n * Provides endpoint registration, discovery, and conflict resolution.\n * \n * **Features:**\n * - Multi-protocol support (REST, GraphQL, OData, WebSocket, etc.)\n * - Route conflict detection with configurable resolution strategies\n * - RBAC permission integration\n * - Dynamic schema linking with ObjectQL references\n * - Plugin API registration\n * \n * **Architecture Alignment:**\n * - Kubernetes: Service Discovery & API Server\n * - AWS API Gateway: Unified API Management\n * - Kong Gateway: Plugin-based API Management\n * \n * @example\n * ```typescript\n * const registry = new ApiRegistry(logger, 'priority');\n * \n * // Register an API\n * registry.registerApi({\n * id: 'customer_api',\n * name: 'Customer API',\n * type: 'rest',\n * version: 'v1',\n * basePath: '/api/v1/customers',\n * endpoints: [...]\n * });\n * \n * // Discover APIs\n * const apis = registry.findApis({ type: 'rest', status: 'active' });\n * \n * // Get registry snapshot\n * const snapshot = registry.getRegistry();\n * ```\n */\nexport class ApiRegistry {\n private apis: Map<string, ApiRegistryEntry> = new Map();\n private endpoints: Map<string, { api: string; endpoint: ApiEndpointRegistration }> = new Map();\n private routes: Map<string, { api: string; endpointId: string; priority: number }> = new Map();\n \n // Performance optimization: Auxiliary indices for O(1) lookups\n private apisByType: Map<string, Set<string>> = new Map();\n private apisByTag: Map<string, Set<string>> = new Map();\n private apisByStatus: Map<string, Set<string>> = new Map();\n \n private conflictResolution: ConflictResolutionStrategy;\n private logger: Logger;\n private version: string;\n private updatedAt: string;\n\n constructor(\n logger: Logger,\n conflictResolution: ConflictResolutionStrategy = 'error',\n version: string = '1.0.0'\n ) {\n this.logger = logger;\n this.conflictResolution = conflictResolution;\n this.version = version;\n this.updatedAt = new Date().toISOString();\n }\n\n /**\n * Register an API with its endpoints\n * \n * @param api - API registry entry\n * @throws Error if API already registered or route conflicts detected\n */\n registerApi(api: ApiRegistryEntryInput): void {\n // Check if API already exists\n if (this.apis.has(api.id)) {\n throw new Error(`[ApiRegistry] API '${api.id}' already registered`);\n }\n\n // Parse and validate the input using Zod schema\n const fullApi = ApiRegistryEntrySchema.parse(api);\n\n // Validate and register endpoints\n for (const endpoint of fullApi.endpoints) {\n this.validateEndpoint(endpoint, fullApi.id);\n }\n\n // Register the API\n this.apis.set(fullApi.id, fullApi);\n \n // Register endpoints\n for (const endpoint of fullApi.endpoints) {\n this.registerEndpoint(fullApi.id, endpoint);\n }\n\n // Update auxiliary indices for performance optimization\n this.updateIndices(fullApi);\n\n this.updatedAt = new Date().toISOString();\n this.logger.info(`API registered: ${fullApi.id}`, {\n api: fullApi.id,\n type: fullApi.type,\n endpointCount: fullApi.endpoints.length,\n });\n }\n\n /**\n * Unregister an API and all its endpoints\n * \n * @param apiId - API identifier\n */\n unregisterApi(apiId: string): void {\n const api = this.apis.get(apiId);\n if (!api) {\n throw new Error(`[ApiRegistry] API '${apiId}' not found`);\n }\n\n // Remove all endpoints\n for (const endpoint of api.endpoints) {\n this.unregisterEndpoint(apiId, endpoint.id);\n }\n\n // Remove from auxiliary indices\n this.removeFromIndices(api);\n\n // Remove the API\n this.apis.delete(apiId);\n this.updatedAt = new Date().toISOString();\n \n this.logger.info(`API unregistered: ${apiId}`);\n }\n\n /**\n * Register a single endpoint\n * \n * @param apiId - API identifier\n * @param endpoint - Endpoint registration\n * @throws Error if route conflict detected\n */\n private registerEndpoint(apiId: string, endpoint: ApiEndpointRegistration): void {\n const endpointKey = `${apiId}:${endpoint.id}`;\n \n // Check if endpoint already registered\n if (this.endpoints.has(endpointKey)) {\n throw new Error(`[ApiRegistry] Endpoint '${endpoint.id}' already registered for API '${apiId}'`);\n }\n\n // Register endpoint\n this.endpoints.set(endpointKey, { api: apiId, endpoint });\n\n // Register route if path is defined\n if (endpoint.path) {\n this.registerRoute(apiId, endpoint);\n }\n }\n\n /**\n * Unregister a single endpoint\n * \n * @param apiId - API identifier\n * @param endpointId - Endpoint identifier\n */\n private unregisterEndpoint(apiId: string, endpointId: string): void {\n const endpointKey = `${apiId}:${endpointId}`;\n const entry = this.endpoints.get(endpointKey);\n \n if (!entry) {\n return; // Already unregistered\n }\n\n // Unregister route\n if (entry.endpoint.path) {\n const routeKey = this.getRouteKey(entry.endpoint);\n this.routes.delete(routeKey);\n }\n\n // Unregister endpoint\n this.endpoints.delete(endpointKey);\n }\n\n /**\n * Register a route with conflict detection\n * \n * @param apiId - API identifier\n * @param endpoint - Endpoint registration\n * @throws Error if route conflict detected (based on strategy)\n */\n private registerRoute(apiId: string, endpoint: ApiEndpointRegistration): void {\n const routeKey = this.getRouteKey(endpoint);\n const priority = endpoint.priority ?? 100;\n const existingRoute = this.routes.get(routeKey);\n\n if (existingRoute) {\n // Route conflict detected\n this.handleRouteConflict(routeKey, apiId, endpoint, existingRoute, priority);\n return;\n }\n\n // Register route\n this.routes.set(routeKey, {\n api: apiId,\n endpointId: endpoint.id,\n priority,\n });\n }\n\n /**\n * Handle route conflict based on resolution strategy\n * \n * @param routeKey - Route key\n * @param apiId - New API identifier\n * @param endpoint - New endpoint\n * @param existingRoute - Existing route registration\n * @param newPriority - New endpoint priority\n * @throws Error if strategy is 'error'\n */\n private handleRouteConflict(\n routeKey: string,\n apiId: string,\n endpoint: ApiEndpointRegistration,\n existingRoute: { api: string; endpointId: string; priority: number },\n newPriority: number\n ): void {\n const strategy = this.conflictResolution;\n\n switch (strategy) {\n case 'error':\n throw new Error(\n `[ApiRegistry] Route conflict detected: '${routeKey}' is already registered by API '${existingRoute.api}' endpoint '${existingRoute.endpointId}'`\n );\n\n case 'priority':\n if (newPriority > existingRoute.priority) {\n // New endpoint has higher priority, replace\n this.logger.warn(\n `Route conflict: replacing '${routeKey}' (priority ${existingRoute.priority} -> ${newPriority})`,\n {\n oldApi: existingRoute.api,\n oldEndpoint: existingRoute.endpointId,\n newApi: apiId,\n newEndpoint: endpoint.id,\n }\n );\n this.routes.set(routeKey, {\n api: apiId,\n endpointId: endpoint.id,\n priority: newPriority,\n });\n } else {\n // Existing endpoint has higher priority, keep it\n this.logger.warn(\n `Route conflict: keeping existing '${routeKey}' (priority ${existingRoute.priority} >= ${newPriority})`,\n {\n existingApi: existingRoute.api,\n existingEndpoint: existingRoute.endpointId,\n newApi: apiId,\n newEndpoint: endpoint.id,\n }\n );\n }\n break;\n\n case 'first-wins':\n // Keep existing route\n this.logger.warn(\n `Route conflict: keeping first registered '${routeKey}'`,\n {\n existingApi: existingRoute.api,\n newApi: apiId,\n }\n );\n break;\n\n case 'last-wins':\n // Replace with new route\n this.logger.warn(\n `Route conflict: replacing with last registered '${routeKey}'`,\n {\n oldApi: existingRoute.api,\n newApi: apiId,\n }\n );\n this.routes.set(routeKey, {\n api: apiId,\n endpointId: endpoint.id,\n priority: newPriority,\n });\n break;\n\n default:\n throw new Error(`[ApiRegistry] Unknown conflict resolution strategy: ${strategy}`);\n }\n }\n\n /**\n * Generate a unique route key for conflict detection\n * \n * NOTE: This implementation uses exact string matching for route conflict detection.\n * It works well for static paths but has limitations with parameterized routes.\n * For example, `/api/users/:id` and `/api/users/:userId` will NOT be detected as conflicts\n * even though they are semantically identical parameterized patterns. Similarly,\n * `/api/:resource/list` and `/api/:entity/list` would also not be detected as conflicting.\n * \n * For more advanced conflict detection (e.g., path-to-regexp pattern matching),\n * consider integrating with your routing library's conflict detection mechanism.\n * \n * @param endpoint - Endpoint registration\n * @returns Route key (e.g., \"GET:/api/v1/customers/:id\")\n */\n private getRouteKey(endpoint: ApiEndpointRegistration): string {\n const method = endpoint.method || 'ANY';\n return `${method}:${endpoint.path}`;\n }\n\n /**\n * Validate endpoint registration\n * \n * @param endpoint - Endpoint to validate\n * @param apiId - API identifier (for error messages)\n * @throws Error if endpoint is invalid\n */\n private validateEndpoint(endpoint: ApiEndpointRegistration, apiId: string): void {\n if (!endpoint.id) {\n throw new Error(`[ApiRegistry] Endpoint in API '${apiId}' missing 'id' field`);\n }\n\n if (!endpoint.path) {\n throw new Error(`[ApiRegistry] Endpoint '${endpoint.id}' in API '${apiId}' missing 'path' field`);\n }\n }\n\n /**\n * Get an API by ID\n * \n * @param apiId - API identifier\n * @returns API registry entry or undefined\n */\n getApi(apiId: string): ApiRegistryEntry | undefined {\n return this.apis.get(apiId);\n }\n\n /**\n * Get all registered APIs\n * \n * @returns Array of all APIs\n */\n getAllApis(): ApiRegistryEntry[] {\n return Array.from(this.apis.values());\n }\n\n /**\n * Find APIs matching query criteria\n * \n * Performance optimized with auxiliary indices for O(1) lookups on type, tags, and status.\n * \n * @param query - Discovery query parameters\n * @returns Matching APIs\n */\n findApis(query: ApiDiscoveryQuery): ApiDiscoveryResponse {\n let resultIds: Set<string> | undefined;\n\n // Use indices for performance-optimized filtering\n // Start with the most restrictive filter to minimize subsequent filtering\n \n // Filter by type (using index for O(1) lookup)\n if (query.type) {\n const typeIds = this.apisByType.get(query.type);\n if (!typeIds || typeIds.size === 0) {\n return { apis: [], total: 0, filters: query };\n }\n resultIds = new Set(typeIds);\n }\n\n // Filter by status (using index for O(1) lookup)\n if (query.status) {\n const statusIds = this.apisByStatus.get(query.status);\n if (!statusIds || statusIds.size === 0) {\n return { apis: [], total: 0, filters: query };\n }\n \n if (resultIds) {\n // Intersect with previous results\n resultIds = new Set([...resultIds].filter(id => statusIds.has(id)));\n } else {\n resultIds = new Set(statusIds);\n }\n \n if (resultIds.size === 0) {\n return { apis: [], total: 0, filters: query };\n }\n }\n\n // Filter by tags (using index for O(M) lookup where M is number of tags)\n if (query.tags && query.tags.length > 0) {\n const tagMatches = new Set<string>();\n \n for (const tag of query.tags) {\n const tagIds = this.apisByTag.get(tag);\n if (tagIds) {\n tagIds.forEach(id => tagMatches.add(id));\n }\n }\n \n if (tagMatches.size === 0) {\n return { apis: [], total: 0, filters: query };\n }\n \n if (resultIds) {\n // Intersect with previous results\n resultIds = new Set([...resultIds].filter(id => tagMatches.has(id)));\n } else {\n resultIds = tagMatches;\n }\n \n if (resultIds.size === 0) {\n return { apis: [], total: 0, filters: query };\n }\n }\n\n // Get the actual API objects\n let results: ApiRegistryEntry[];\n if (resultIds) {\n results = Array.from(resultIds)\n .map(id => this.apis.get(id))\n .filter((api): api is ApiRegistryEntry => api !== undefined);\n } else {\n results = Array.from(this.apis.values());\n }\n\n // Apply remaining filters that don't have indices (less common filters)\n \n // Filter by plugin source\n if (query.pluginSource) {\n results = results.filter(\n (api) => api.metadata?.pluginSource === query.pluginSource\n );\n }\n\n // Filter by version\n if (query.version) {\n results = results.filter((api) => api.version === query.version);\n }\n\n // Search in name/description\n if (query.search) {\n const searchLower = query.search.toLowerCase();\n results = results.filter(\n (api) =>\n api.name.toLowerCase().includes(searchLower) ||\n (api.description && api.description.toLowerCase().includes(searchLower))\n );\n }\n\n return {\n apis: results,\n total: results.length,\n filters: query,\n };\n }\n\n /**\n * Get endpoint by API ID and endpoint ID\n * \n * @param apiId - API identifier\n * @param endpointId - Endpoint identifier\n * @returns Endpoint registration or undefined\n */\n getEndpoint(apiId: string, endpointId: string): ApiEndpointRegistration | undefined {\n const key = `${apiId}:${endpointId}`;\n return this.endpoints.get(key)?.endpoint;\n }\n\n /**\n * Find endpoint by route (method + path)\n * \n * @param method - HTTP method\n * @param path - URL path\n * @returns Endpoint registration or undefined\n */\n findEndpointByRoute(method: string, path: string): {\n api: ApiRegistryEntry;\n endpoint: ApiEndpointRegistration;\n } | undefined {\n const routeKey = `${method}:${path}`;\n const route = this.routes.get(routeKey);\n \n if (!route) {\n return undefined;\n }\n\n const api = this.apis.get(route.api);\n const endpoint = this.getEndpoint(route.api, route.endpointId);\n\n if (!api || !endpoint) {\n return undefined;\n }\n\n return { api, endpoint };\n }\n\n /**\n * Get complete registry snapshot\n * \n * @returns Current registry state\n */\n getRegistry(): ApiRegistryType {\n const apis = Array.from(this.apis.values());\n \n // Group by type\n const byType: Record<string, ApiRegistryEntry[]> = {};\n for (const api of apis) {\n if (!byType[api.type]) {\n byType[api.type] = [];\n }\n byType[api.type].push(api);\n }\n\n // Group by status\n const byStatus: Record<string, ApiRegistryEntry[]> = {};\n for (const api of apis) {\n const status = api.metadata?.status || 'active';\n if (!byStatus[status]) {\n byStatus[status] = [];\n }\n byStatus[status].push(api);\n }\n\n // Count total endpoints\n const totalEndpoints = apis.reduce(\n (sum, api) => sum + api.endpoints.length,\n 0\n );\n\n return {\n version: this.version,\n conflictResolution: this.conflictResolution,\n apis,\n totalApis: apis.length,\n totalEndpoints,\n byType,\n byStatus,\n updatedAt: this.updatedAt,\n };\n }\n\n /**\n * Clear all registered APIs\n * \n * **⚠️ SAFETY WARNING:**\n * This method clears all registered APIs and should be used with caution.\n * \n * **Usage Restrictions:**\n * - In production environments (NODE_ENV=production), a `force: true` parameter is required\n * - Primarily intended for testing and development hot-reload scenarios\n * \n * @param options - Clear options\n * @param options.force - Force clear in production environment (default: false)\n * @throws Error if called in production without force flag\n * \n * @example Safe usage in tests\n * ```typescript\n * beforeEach(() => {\n * registry.clear(); // OK in test environment\n * });\n * ```\n * \n * @example Usage in production (requires explicit force)\n * ```typescript\n * // In production, explicit force is required\n * registry.clear({ force: true });\n * ```\n */\n clear(options: { force?: boolean } = {}): void {\n const isProduction = this.isProductionEnvironment();\n \n if (isProduction && !options.force) {\n throw new Error(\n '[ApiRegistry] Cannot clear registry in production environment without force flag. ' +\n 'Use clear({ force: true }) if you really want to clear the registry.'\n );\n }\n\n this.apis.clear();\n this.endpoints.clear();\n this.routes.clear();\n \n // Clear auxiliary indices\n this.apisByType.clear();\n this.apisByTag.clear();\n this.apisByStatus.clear();\n \n this.updatedAt = new Date().toISOString();\n \n if (isProduction) {\n this.logger.warn('API registry forcefully cleared in production', { force: options.force });\n } else {\n this.logger.info('API registry cleared');\n }\n }\n\n /**\n * Get registry statistics\n * \n * @returns Registry statistics\n */\n getStats(): {\n totalApis: number;\n totalEndpoints: number;\n totalRoutes: number;\n apisByType: Record<string, number>;\n endpointsByApi: Record<string, number>;\n } {\n const apis = Array.from(this.apis.values());\n \n const apisByType: Record<string, number> = {};\n for (const api of apis) {\n apisByType[api.type] = (apisByType[api.type] || 0) + 1;\n }\n\n const endpointsByApi: Record<string, number> = {};\n for (const api of apis) {\n endpointsByApi[api.id] = api.endpoints.length;\n }\n\n return {\n totalApis: this.apis.size,\n totalEndpoints: this.endpoints.size,\n totalRoutes: this.routes.size,\n apisByType,\n endpointsByApi,\n };\n }\n\n /**\n * Update auxiliary indices when an API is registered\n * \n * @param api - API entry to index\n * @private\n * @internal\n */\n private updateIndices(api: ApiRegistryEntry): void {\n // Index by type\n this.ensureIndexSet(this.apisByType, api.type).add(api.id);\n\n // Index by status\n const status = api.metadata?.status || 'active';\n this.ensureIndexSet(this.apisByStatus, status).add(api.id);\n\n // Index by tags\n const tags = api.metadata?.tags || [];\n for (const tag of tags) {\n this.ensureIndexSet(this.apisByTag, tag).add(api.id);\n }\n }\n\n /**\n * Remove API from auxiliary indices when unregistered\n * \n * @param api - API entry to remove from indices\n * @private\n * @internal\n */\n private removeFromIndices(api: ApiRegistryEntry): void {\n // Remove from type index\n this.removeFromIndexSet(this.apisByType, api.type, api.id);\n\n // Remove from status index\n const status = api.metadata?.status || 'active';\n this.removeFromIndexSet(this.apisByStatus, status, api.id);\n\n // Remove from tag indices\n const tags = api.metadata?.tags || [];\n for (const tag of tags) {\n this.removeFromIndexSet(this.apisByTag, tag, api.id);\n }\n }\n\n /**\n * Helper to ensure an index set exists and return it\n * \n * @param map - Index map\n * @param key - Index key\n * @returns The Set for this key (created if needed)\n * @private\n * @internal\n */\n private ensureIndexSet(map: Map<string, Set<string>>, key: string): Set<string> {\n let set = map.get(key);\n if (!set) {\n set = new Set();\n map.set(key, set);\n }\n return set;\n }\n\n /**\n * Helper to remove an ID from an index set and clean up empty sets\n * \n * @param map - Index map\n * @param key - Index key\n * @param id - API ID to remove\n * @private\n * @internal\n */\n private removeFromIndexSet(map: Map<string, Set<string>>, key: string, id: string): void {\n const set = map.get(key);\n if (set) {\n set.delete(id);\n // Clean up empty sets to avoid memory leaks\n if (set.size === 0) {\n map.delete(key);\n }\n }\n }\n\n /**\n * Check if running in production environment\n * \n * @returns true if NODE_ENV is 'production'\n * @private\n * @internal\n */\n private isProductionEnvironment(): boolean {\n return getEnv('NODE_ENV') === 'production';\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { Plugin, PluginContext } from './types.js';\nimport { ApiRegistry } from './api-registry.js';\nimport type { ConflictResolutionStrategy } from '@objectstack/spec/api';\n\n/**\n * API Registry Plugin Configuration\n */\nexport interface ApiRegistryPluginConfig {\n /**\n * Conflict resolution strategy for route conflicts\n * @default 'error'\n */\n conflictResolution?: ConflictResolutionStrategy;\n \n /**\n * Registry version\n * @default '1.0.0'\n */\n version?: string;\n}\n\n/**\n * API Registry Plugin\n * \n * Registers the API Registry service in the kernel, making it available\n * to all plugins for endpoint registration and discovery.\n * \n * **Usage:**\n * ```typescript\n * const kernel = new ObjectKernel();\n * \n * // Register API Registry Plugin\n * kernel.use(createApiRegistryPlugin({ conflictResolution: 'priority' }));\n * \n * // In other plugins, access the API Registry\n * const plugin: Plugin = {\n * name: 'my-plugin',\n * init: async (ctx) => {\n * const registry = ctx.getService<ApiRegistry>('api-registry');\n * \n * // Register plugin APIs\n * registry.registerApi({\n * id: 'my_plugin_api',\n * name: 'My Plugin API',\n * type: 'rest',\n * version: 'v1',\n * basePath: '/api/v1/my-plugin',\n * endpoints: [...]\n * });\n * }\n * };\n * ```\n * \n * @param config - Plugin configuration\n * @returns Plugin instance\n */\nexport function createApiRegistryPlugin(\n config: ApiRegistryPluginConfig = {}\n): Plugin {\n const {\n conflictResolution = 'error',\n version = '1.0.0',\n } = config;\n\n return {\n name: 'com.objectstack.core.api-registry',\n type: 'standard',\n version: '1.0.0',\n\n init: async (ctx: PluginContext) => {\n // Create API Registry instance\n const registry = new ApiRegistry(\n ctx.logger,\n conflictResolution,\n version\n );\n\n // Register as a service\n ctx.registerService('api-registry', registry);\n\n ctx.logger.info('API Registry plugin initialized', {\n conflictResolution,\n version,\n });\n },\n };\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nexport * from './adapter.js';\nexport * from './runner.js';\nexport * from './http-adapter.js';\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { QA } from '@objectstack/spec';\nimport { TestExecutionAdapter } from './adapter.js';\n\nexport interface TestResult {\n scenarioId: string;\n passed: boolean;\n steps: StepResult[];\n error?: unknown;\n duration: number;\n}\n\nexport interface StepResult {\n stepName: string;\n passed: boolean;\n error?: unknown;\n output?: unknown;\n duration: number;\n}\n\nexport class TestRunner {\n constructor(private adapter: TestExecutionAdapter) {}\n\n async runSuite(suite: QA.TestSuite): Promise<TestResult[]> {\n const results: TestResult[] = [];\n for (const scenario of suite.scenarios) {\n results.push(await this.runScenario(scenario));\n }\n return results;\n }\n\n async runScenario(scenario: QA.TestScenario): Promise<TestResult> {\n const startTime = Date.now();\n const context: Record<string, unknown> = {}; // Variable context\n \n // Initialize context from initial payload if needed? Currently schema doesn't have initial context prop on Scenario\n // But we defined TestContextSchema separately.\n \n // Setup\n if (scenario.setup) {\n for (const step of scenario.setup) {\n try {\n await this.runStep(step, context);\n } catch (e) {\n return {\n scenarioId: scenario.id,\n passed: false,\n steps: [],\n error: `Setup failed: ${e instanceof Error ? e.message : String(e)}`,\n duration: Date.now() - startTime\n };\n }\n }\n }\n\n const stepResults: StepResult[] = [];\n let scenarioPassed = true;\n let scenarioError: unknown = undefined;\n\n // Main Steps\n for (const step of scenario.steps) {\n const stepStartTime = Date.now();\n try {\n const output = await this.runStep(step, context);\n stepResults.push({\n stepName: step.name,\n passed: true,\n output,\n duration: Date.now() - stepStartTime\n });\n } catch (e) {\n scenarioPassed = false;\n scenarioError = e;\n stepResults.push({\n stepName: step.name,\n passed: false,\n error: e,\n duration: Date.now() - stepStartTime\n });\n break; // Stop on first failure\n }\n }\n\n // Teardown (run even if failed)\n if (scenario.teardown) {\n for (const step of scenario.teardown) {\n try {\n await this.runStep(step, context);\n } catch (e) {\n // Log teardown failure but don't override main failure if it exists\n if (scenarioPassed) {\n scenarioPassed = false;\n scenarioError = `Teardown failed: ${e instanceof Error ? e.message : String(e)}`;\n }\n }\n }\n }\n\n return {\n scenarioId: scenario.id,\n passed: scenarioPassed,\n steps: stepResults,\n error: scenarioError,\n duration: Date.now() - startTime\n };\n }\n\n private async runStep(step: QA.TestStep, context: Record<string, unknown>): Promise<unknown> {\n // 1. Resolve Variables with Context (Simple interpolation or just pass context?)\n // For now, assume adpater handles context resolution or we do basic replacement\n const resolvedAction = this.resolveVariables(step.action, context);\n\n // 2. Execute Action\n const result = await this.adapter.execute(resolvedAction, context);\n\n // 3. Capture Outputs\n if (step.capture) {\n for (const [varName, path] of Object.entries(step.capture)) {\n context[varName] = this.getValueByPath(result, path);\n }\n }\n\n // 4. Run Assertions\n if (step.assertions) {\n for (const assertion of step.assertions) {\n this.assert(result, assertion, context);\n }\n }\n\n return result;\n }\n\n private resolveVariables(action: QA.TestAction, _context: Record<string, unknown>): QA.TestAction {\n // TODO: Implement JSON path variable substitution stringify/parse\n // For now returning as is\n return action; \n }\n\n private getValueByPath(obj: unknown, path: string): unknown {\n if (!path) return obj;\n const parts = path.split('.');\n let current: any = obj;\n for (const part of parts) {\n if (current === null || current === undefined) return undefined;\n current = current[part];\n }\n return current;\n }\n\n private assert(result: unknown, assertion: QA.TestAssertion, _context: Record<string, unknown>) {\n const actual = this.getValueByPath(result, assertion.field);\n // Resolve expected value if it's a variable ref? \n const expected = assertion.expectedValue; // Simplify for now\n\n switch (assertion.operator) {\n case 'equals':\n if (actual !== expected) throw new Error(`Assertion failed: ${assertion.field} expected ${expected}, got ${actual}`);\n break;\n case 'not_equals':\n if (actual === expected) throw new Error(`Assertion failed: ${assertion.field} expected not ${expected}, got ${actual}`);\n break;\n case 'contains':\n if (Array.isArray(actual)) {\n if (!actual.includes(expected)) throw new Error(`Assertion failed: ${assertion.field} array does not contain ${expected}`);\n } else if (typeof actual === 'string') {\n if (!actual.includes(String(expected))) throw new Error(`Assertion failed: ${assertion.field} string does not contain ${expected}`);\n }\n break;\n case 'not_null':\n if (actual === null || actual === undefined) throw new Error(`Assertion failed: ${assertion.field} is null`);\n break;\n case 'is_null':\n if (actual !== null && actual !== undefined) throw new Error(`Assertion failed: ${assertion.field} is not null`);\n break;\n // ... Add other operators\n default:\n throw new Error(`Unknown assertion operator: ${assertion.operator}`);\n }\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { QA } from '@objectstack/spec';\nimport { TestExecutionAdapter } from './adapter.js';\n\nexport class HttpTestAdapter implements TestExecutionAdapter {\n constructor(private baseUrl: string, private authToken?: string) {}\n\n async execute(action: QA.TestAction, _context: Record<string, unknown>): Promise<unknown> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n if (this.authToken) {\n headers['Authorization'] = `Bearer ${this.authToken}`;\n }\n // If action.user is specified, maybe add a specific header for impersonation if supported?\n if (action.user) {\n headers['X-Run-As'] = action.user;\n }\n\n switch (action.type) {\n case 'create_record':\n return this.createRecord(action.target, action.payload || {}, headers);\n case 'update_record':\n return this.updateRecord(action.target, action.payload || {}, headers);\n case 'delete_record':\n return this.deleteRecord(action.target, action.payload || {}, headers);\n case 'read_record':\n return this.readRecord(action.target, action.payload || {}, headers);\n case 'query_records':\n return this.queryRecords(action.target, action.payload || {}, headers);\n case 'api_call':\n return this.rawApiCall(action.target, action.payload || {}, headers);\n case 'wait':\n const ms = Number(action.payload?.duration || 1000);\n return new Promise(resolve => setTimeout(() => resolve({ waited: ms }), ms));\n default:\n throw new Error(`Unsupported action type in HttpAdapter: ${action.type}`);\n }\n }\n\n private async createRecord(objectName: string, data: Record<string, unknown>, headers: Record<string, string>) {\n const response = await fetch(`${this.baseUrl}/api/data/${objectName}`, {\n method: 'POST',\n headers,\n body: JSON.stringify(data)\n });\n return this.handleResponse(response);\n }\n\n private async updateRecord(objectName: string, data: Record<string, unknown>, headers: Record<string, string>) {\n const id = data._id || data.id;\n if (!id) throw new Error('Update record requires _id or id in payload');\n const response = await fetch(`${this.baseUrl}/api/data/${objectName}/${id}`, {\n method: 'PUT',\n headers,\n body: JSON.stringify(data)\n });\n return this.handleResponse(response);\n }\n\n private async deleteRecord(objectName: string, data: Record<string, unknown>, headers: Record<string, string>) {\n const id = data._id || data.id;\n if (!id) throw new Error('Delete record requires _id or id in payload');\n const response = await fetch(`${this.baseUrl}/api/data/${objectName}/${id}`, {\n method: 'DELETE',\n headers\n });\n return this.handleResponse(response);\n }\n\n private async readRecord(objectName: string, data: Record<string, unknown>, headers: Record<string, string>) {\n const id = data._id || data.id;\n if (!id) throw new Error('Read record requires _id or id in payload');\n const response = await fetch(`${this.baseUrl}/api/data/${objectName}/${id}`, {\n method: 'GET',\n headers\n });\n return this.handleResponse(response);\n }\n\n private async queryRecords(objectName: string, data: Record<string, unknown>, headers: Record<string, string>) {\n // Assuming query via POST or GraphQL-like endpoint\n const response = await fetch(`${this.baseUrl}/api/data/${objectName}/query`, {\n method: 'POST',\n headers,\n body: JSON.stringify(data)\n });\n return this.handleResponse(response);\n }\n\n private async rawApiCall(endpoint: string, data: Record<string, unknown>, headers: Record<string, string>) {\n const method = (data.method as string) || 'GET';\n const body = data.body ? JSON.stringify(data.body) : undefined;\n const url = endpoint.startsWith('http') ? endpoint : `${this.baseUrl}${endpoint}`;\n \n const response = await fetch(url, {\n method,\n headers,\n body\n });\n return this.handleResponse(response);\n }\n\n private async handleResponse(response: Response) {\n if (!response.ok) {\n const text = await response.text();\n throw new Error(`HTTP Error ${response.status}: ${text}`);\n }\n const contentType = response.headers.get('content-type');\n if (contentType && contentType.includes('application/json')) {\n return response.json();\n }\n return response.text();\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { Logger } from '@objectstack/spec/contracts';\nimport type { PluginMetadata } from '../plugin-loader.js';\n\n// Conditionally import crypto for Node.js environments\nlet cryptoModule: typeof import('crypto') | null = null;\n\n\n/**\n * Plugin Signature Configuration\n * Controls how plugin signatures are verified\n */\nexport interface PluginSignatureConfig {\n /**\n * Map of publisher IDs to their trusted public keys\n * Format: { 'com.objectstack': '-----BEGIN PUBLIC KEY-----...' }\n */\n trustedPublicKeys: Map<string, string>;\n \n /**\n * Signature algorithm to use\n * - RS256: RSA with SHA-256\n * - ES256: ECDSA with SHA-256\n */\n algorithm: 'RS256' | 'ES256';\n \n /**\n * Strict mode: reject plugins without signatures\n * - true: All plugins must be signed\n * - false: Unsigned plugins are allowed with warning\n */\n strictMode: boolean;\n \n /**\n * Allow self-signed plugins in development\n */\n allowSelfSigned?: boolean;\n}\n\n/**\n * Plugin Signature Verification Result\n */\nexport interface SignatureVerificationResult {\n verified: boolean;\n error?: string;\n publisherId?: string;\n algorithm?: string;\n signedAt?: Date;\n}\n\n/**\n * Plugin Signature Verifier\n * \n * Implements cryptographic verification of plugin signatures to ensure:\n * 1. Plugin integrity - code hasn't been tampered with\n * 2. Publisher authenticity - plugin comes from trusted source\n * 3. Non-repudiation - publisher cannot deny signing\n * \n * Architecture:\n * - Uses Node.js crypto module for signature verification\n * - Supports RSA (RS256) and ECDSA (ES256) algorithms\n * - Verifies against trusted public key registry\n * - Computes hash of plugin code for integrity check\n * \n * Security Model:\n * - Public keys are pre-registered and trusted\n * - Plugin signature is verified before loading\n * - Strict mode rejects unsigned plugins\n * - Development mode allows self-signed plugins\n */\nexport class PluginSignatureVerifier {\n private config: PluginSignatureConfig;\n private logger: Logger;\n \n constructor(config: PluginSignatureConfig, logger: Logger) {\n this.config = config;\n this.logger = logger;\n \n this.validateConfig();\n }\n \n /**\n * Verify plugin signature\n * \n * @param plugin - Plugin metadata with signature\n * @returns Verification result\n * @throws Error if verification fails in strict mode\n */\n async verifyPluginSignature(plugin: PluginMetadata): Promise<SignatureVerificationResult> {\n // Handle unsigned plugins\n if (!plugin.signature) {\n return this.handleUnsignedPlugin(plugin);\n }\n \n try {\n // 1. Extract publisher ID from plugin name (reverse domain notation)\n const publisherId = this.extractPublisherId(plugin.name);\n \n // 2. Get trusted public key for publisher\n const publicKey = this.config.trustedPublicKeys.get(publisherId);\n if (!publicKey) {\n const error = `No trusted public key for publisher: ${publisherId}`;\n this.logger.warn(error, { plugin: plugin.name, publisherId });\n \n if (this.config.strictMode && !this.config.allowSelfSigned) {\n throw new Error(error);\n }\n \n return {\n verified: false,\n error,\n publisherId,\n };\n }\n \n // 3. Compute plugin code hash\n const pluginHash = this.computePluginHash(plugin);\n \n // 4. Verify signature using crypto module\n const isValid = await this.verifyCryptoSignature(\n pluginHash,\n plugin.signature,\n publicKey\n );\n \n if (!isValid) {\n const error = `Signature verification failed for plugin: ${plugin.name}`;\n this.logger.error(error, undefined, { plugin: plugin.name, publisherId });\n throw new Error(error);\n }\n \n this.logger.info(`✅ Plugin signature verified: ${plugin.name}`, {\n plugin: plugin.name,\n publisherId,\n algorithm: this.config.algorithm,\n });\n \n return {\n verified: true,\n publisherId,\n algorithm: this.config.algorithm,\n };\n \n } catch (error) {\n this.logger.error(`Signature verification error: ${plugin.name}`, error as Error);\n \n if (this.config.strictMode) {\n throw error;\n }\n \n return {\n verified: false,\n error: (error as Error).message,\n };\n }\n }\n \n /**\n * Register a trusted public key for a publisher\n */\n registerPublicKey(publisherId: string, publicKey: string): void {\n this.config.trustedPublicKeys.set(publisherId, publicKey);\n this.logger.info(`Trusted public key registered for: ${publisherId}`);\n }\n \n /**\n * Remove a trusted public key\n */\n revokePublicKey(publisherId: string): void {\n this.config.trustedPublicKeys.delete(publisherId);\n this.logger.warn(`Public key revoked for: ${publisherId}`);\n }\n \n /**\n * Get list of trusted publishers\n */\n getTrustedPublishers(): string[] {\n return Array.from(this.config.trustedPublicKeys.keys());\n }\n \n // Private methods\n \n private handleUnsignedPlugin(plugin: PluginMetadata): SignatureVerificationResult {\n if (this.config.strictMode) {\n const error = `Plugin missing signature (strict mode): ${plugin.name}`;\n this.logger.error(error, undefined, { plugin: plugin.name });\n throw new Error(error);\n }\n \n this.logger.warn(`⚠️ Plugin not signed: ${plugin.name}`, {\n plugin: plugin.name,\n recommendation: 'Consider signing plugins for production environments',\n });\n \n return {\n verified: false,\n error: 'Plugin not signed',\n };\n }\n \n private extractPublisherId(pluginName: string): string {\n // Extract publisher from reverse domain notation\n // Example: \"com.objectstack.engine.objectql\" -> \"com.objectstack\"\n const parts = pluginName.split('.');\n \n if (parts.length < 2) {\n throw new Error(`Invalid plugin name format: ${pluginName} (expected reverse domain notation)`);\n }\n \n // Return first two parts (domain reversed)\n return `${parts[0]}.${parts[1]}`;\n }\n \n private computePluginHash(plugin: PluginMetadata): string {\n // In browser environment, use SubtleCrypto\n if (typeof (globalThis as any).window !== 'undefined') {\n return this.computePluginHashBrowser(plugin);\n }\n \n // In Node.js environment, use crypto module\n return this.computePluginHashNode(plugin);\n }\n \n private computePluginHashNode(plugin: PluginMetadata): string {\n // Use pre-loaded crypto module\n if (!cryptoModule) {\n this.logger.warn('crypto module not available, using fallback hash');\n return this.computePluginHashFallback(plugin);\n }\n \n // Compute hash of plugin code\n const pluginCode = this.serializePluginCode(plugin);\n return cryptoModule.createHash('sha256').update(pluginCode).digest('hex');\n }\n \n private computePluginHashBrowser(plugin: PluginMetadata): string {\n // Browser environment - use simple hash for now\n // In production, should use SubtleCrypto for proper cryptographic hash\n this.logger.debug('Using browser hash (SubtleCrypto integration pending)');\n return this.computePluginHashFallback(plugin);\n }\n \n private computePluginHashFallback(plugin: PluginMetadata): string {\n // Simple hash fallback (not cryptographically secure)\n const pluginCode = this.serializePluginCode(plugin);\n let hash = 0;\n \n for (let i = 0; i < pluginCode.length; i++) {\n const char = pluginCode.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n \n return hash.toString(16);\n }\n \n private serializePluginCode(plugin: PluginMetadata): string {\n // Serialize plugin code for hashing\n // Include init, start, destroy functions\n const parts: string[] = [\n plugin.name,\n plugin.version,\n plugin.init.toString(),\n ];\n \n if (plugin.start) {\n parts.push(plugin.start.toString());\n }\n \n if (plugin.destroy) {\n parts.push(plugin.destroy.toString());\n }\n \n return parts.join('|');\n }\n \n private async verifyCryptoSignature(\n data: string,\n signature: string,\n publicKey: string\n ): Promise<boolean> {\n // In browser environment, use SubtleCrypto\n if (typeof (globalThis as any).window !== 'undefined') {\n return this.verifyCryptoSignatureBrowser(data, signature, publicKey);\n }\n \n // In Node.js environment, use crypto module\n return this.verifyCryptoSignatureNode(data, signature, publicKey);\n }\n \n private async verifyCryptoSignatureNode(\n data: string,\n signature: string,\n publicKey: string\n ): Promise<boolean> {\n if (!cryptoModule) {\n try {\n // @ts-ignore\n cryptoModule = await import('crypto');\n } catch (e) {\n // ignore\n }\n }\n\n if (!cryptoModule) {\n this.logger.error('Crypto module not available for signature verification');\n return false;\n }\n \n try {\n // Create verify object based on algorithm\n if (this.config.algorithm === 'ES256') {\n // ECDSA verification - requires lowercase 'sha256'\n const verify = cryptoModule.createVerify('sha256');\n verify.update(data);\n return verify.verify(\n {\n key: publicKey,\n format: 'pem',\n type: 'spki',\n },\n signature,\n 'base64'\n );\n } else {\n // RSA verification (RS256)\n const verify = cryptoModule.createVerify('RSA-SHA256');\n verify.update(data);\n return verify.verify(publicKey, signature, 'base64');\n }\n } catch (error) {\n this.logger.error('Signature verification failed', error as Error);\n return false;\n }\n }\n \n private async verifyCryptoSignatureBrowser(\n _data: string,\n _signature: string,\n _publicKey: string\n ): Promise<boolean> {\n // Browser implementation using SubtleCrypto\n // TODO: Implement SubtleCrypto-based verification\n this.logger.warn('Browser signature verification not yet implemented');\n return false;\n }\n \n private validateConfig(): void {\n if (!this.config.trustedPublicKeys || this.config.trustedPublicKeys.size === 0) {\n this.logger.warn('No trusted public keys configured - all signatures will fail');\n }\n \n if (!this.config.algorithm) {\n throw new Error('Signature algorithm must be specified');\n }\n \n if (!['RS256', 'ES256'].includes(this.config.algorithm)) {\n throw new Error(`Unsupported algorithm: ${this.config.algorithm}`);\n }\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { Logger } from '@objectstack/spec/contracts';\nimport type { PluginCapability } from '@objectstack/spec/kernel';\nimport type { PluginContext } from '../types.js';\n\n/**\n * Plugin Permissions\n * Defines what actions a plugin is allowed to perform\n */\nexport interface PluginPermissions {\n canAccessService(serviceName: string): boolean;\n canTriggerHook(hookName: string): boolean;\n canReadFile(path: string): boolean;\n canWriteFile(path: string): boolean;\n canNetworkRequest(url: string): boolean;\n}\n\n/**\n * Permission Check Result\n */\nexport interface PermissionCheckResult {\n allowed: boolean;\n reason?: string;\n capability?: string;\n}\n\n/**\n * Plugin Permission Enforcer\n * \n * Implements capability-based security model to enforce:\n * 1. Service access control - which services a plugin can use\n * 2. Hook restrictions - which hooks a plugin can trigger\n * 3. File system permissions - what files a plugin can read/write\n * 4. Network permissions - what URLs a plugin can access\n * \n * Architecture:\n * - Uses capability declarations from plugin manifest\n * - Checks permissions before allowing operations\n * - Logs all permission denials for security audit\n * - Supports allowlist and denylist patterns\n * \n * Security Model:\n * - Principle of least privilege - plugins get minimal permissions\n * - Explicit declaration - all capabilities must be declared\n * - Runtime enforcement - checks happen at operation time\n * - Audit trail - all denials are logged\n * \n * Usage:\n * ```typescript\n * const enforcer = new PluginPermissionEnforcer(logger);\n * enforcer.registerPluginPermissions(pluginName, capabilities);\n * enforcer.enforceServiceAccess(pluginName, 'database');\n * ```\n */\nexport class PluginPermissionEnforcer {\n private logger: Logger;\n private permissionRegistry: Map<string, PluginPermissions> = new Map();\n private capabilityRegistry: Map<string, PluginCapability[]> = new Map();\n \n constructor(logger: Logger) {\n this.logger = logger;\n }\n \n /**\n * Register plugin capabilities and build permission set\n * \n * @param pluginName - Plugin identifier\n * @param capabilities - Array of capability declarations\n */\n registerPluginPermissions(pluginName: string, capabilities: PluginCapability[]): void {\n this.capabilityRegistry.set(pluginName, capabilities);\n \n const permissions: PluginPermissions = {\n canAccessService: (service) => this.checkServiceAccess(capabilities, service),\n canTriggerHook: (hook) => this.checkHookAccess(capabilities, hook),\n canReadFile: (path) => this.checkFileRead(capabilities, path),\n canWriteFile: (path) => this.checkFileWrite(capabilities, path),\n canNetworkRequest: (url) => this.checkNetworkAccess(capabilities, url),\n };\n \n this.permissionRegistry.set(pluginName, permissions);\n \n this.logger.info(`Permissions registered for plugin: ${pluginName}`, {\n plugin: pluginName,\n capabilityCount: capabilities.length,\n });\n }\n \n /**\n * Enforce service access permission\n * \n * @param pluginName - Plugin requesting access\n * @param serviceName - Service to access\n * @throws Error if permission denied\n */\n enforceServiceAccess(pluginName: string, serviceName: string): void {\n const result = this.checkPermission(pluginName, (perms) => perms.canAccessService(serviceName));\n \n if (!result.allowed) {\n const error = `Permission denied: Plugin ${pluginName} cannot access service ${serviceName}`;\n this.logger.warn(error, {\n plugin: pluginName,\n service: serviceName,\n reason: result.reason,\n });\n throw new Error(error);\n }\n \n this.logger.debug(`Service access granted: ${pluginName} -> ${serviceName}`);\n }\n \n /**\n * Enforce hook trigger permission\n * \n * @param pluginName - Plugin requesting access\n * @param hookName - Hook to trigger\n * @throws Error if permission denied\n */\n enforceHookTrigger(pluginName: string, hookName: string): void {\n const result = this.checkPermission(pluginName, (perms) => perms.canTriggerHook(hookName));\n \n if (!result.allowed) {\n const error = `Permission denied: Plugin ${pluginName} cannot trigger hook ${hookName}`;\n this.logger.warn(error, {\n plugin: pluginName,\n hook: hookName,\n reason: result.reason,\n });\n throw new Error(error);\n }\n \n this.logger.debug(`Hook trigger granted: ${pluginName} -> ${hookName}`);\n }\n \n /**\n * Enforce file read permission\n * \n * @param pluginName - Plugin requesting access\n * @param path - File path to read\n * @throws Error if permission denied\n */\n enforceFileRead(pluginName: string, path: string): void {\n const result = this.checkPermission(pluginName, (perms) => perms.canReadFile(path));\n \n if (!result.allowed) {\n const error = `Permission denied: Plugin ${pluginName} cannot read file ${path}`;\n this.logger.warn(error, {\n plugin: pluginName,\n path,\n reason: result.reason,\n });\n throw new Error(error);\n }\n \n this.logger.debug(`File read granted: ${pluginName} -> ${path}`);\n }\n \n /**\n * Enforce file write permission\n * \n * @param pluginName - Plugin requesting access\n * @param path - File path to write\n * @throws Error if permission denied\n */\n enforceFileWrite(pluginName: string, path: string): void {\n const result = this.checkPermission(pluginName, (perms) => perms.canWriteFile(path));\n \n if (!result.allowed) {\n const error = `Permission denied: Plugin ${pluginName} cannot write file ${path}`;\n this.logger.warn(error, {\n plugin: pluginName,\n path,\n reason: result.reason,\n });\n throw new Error(error);\n }\n \n this.logger.debug(`File write granted: ${pluginName} -> ${path}`);\n }\n \n /**\n * Enforce network request permission\n * \n * @param pluginName - Plugin requesting access\n * @param url - URL to access\n * @throws Error if permission denied\n */\n enforceNetworkRequest(pluginName: string, url: string): void {\n const result = this.checkPermission(pluginName, (perms) => perms.canNetworkRequest(url));\n \n if (!result.allowed) {\n const error = `Permission denied: Plugin ${pluginName} cannot access URL ${url}`;\n this.logger.warn(error, {\n plugin: pluginName,\n url,\n reason: result.reason,\n });\n throw new Error(error);\n }\n \n this.logger.debug(`Network request granted: ${pluginName} -> ${url}`);\n }\n \n /**\n * Get plugin capabilities\n * \n * @param pluginName - Plugin identifier\n * @returns Array of capabilities or undefined\n */\n getPluginCapabilities(pluginName: string): PluginCapability[] | undefined {\n return this.capabilityRegistry.get(pluginName);\n }\n \n /**\n * Get plugin permissions\n * \n * @param pluginName - Plugin identifier\n * @returns Permissions object or undefined\n */\n getPluginPermissions(pluginName: string): PluginPermissions | undefined {\n return this.permissionRegistry.get(pluginName);\n }\n \n /**\n * Revoke all permissions for a plugin\n * \n * @param pluginName - Plugin identifier\n */\n revokePermissions(pluginName: string): void {\n this.permissionRegistry.delete(pluginName);\n this.capabilityRegistry.delete(pluginName);\n this.logger.warn(`Permissions revoked for plugin: ${pluginName}`);\n }\n \n // Private methods\n \n private checkPermission(\n pluginName: string,\n check: (perms: PluginPermissions) => boolean\n ): PermissionCheckResult {\n const permissions = this.permissionRegistry.get(pluginName);\n \n if (!permissions) {\n return {\n allowed: false,\n reason: 'Plugin permissions not registered',\n };\n }\n \n const allowed = check(permissions);\n \n return {\n allowed,\n reason: allowed ? undefined : 'No matching capability found',\n };\n }\n \n private checkServiceAccess(capabilities: PluginCapability[], serviceName: string): boolean {\n // Check if plugin has capability to access this service\n return capabilities.some(cap => {\n const protocolId = cap.protocol.id;\n \n // Check for wildcard service access\n if (protocolId.includes('protocol.service.all')) {\n return true;\n }\n \n // Check for specific service protocol\n if (protocolId.includes(`protocol.service.${serviceName}`)) {\n return true;\n }\n \n // Check for service category match\n const serviceCategory = serviceName.split('.')[0];\n if (protocolId.includes(`protocol.service.${serviceCategory}`)) {\n return true;\n }\n \n return false;\n });\n }\n \n private checkHookAccess(capabilities: PluginCapability[], hookName: string): boolean {\n // Check if plugin has capability to trigger this hook\n return capabilities.some(cap => {\n const protocolId = cap.protocol.id;\n \n // Check for wildcard hook access\n if (protocolId.includes('protocol.hook.all')) {\n return true;\n }\n \n // Check for specific hook protocol\n if (protocolId.includes(`protocol.hook.${hookName}`)) {\n return true;\n }\n \n // Check for hook category match\n const hookCategory = hookName.split(':')[0];\n if (protocolId.includes(`protocol.hook.${hookCategory}`)) {\n return true;\n }\n \n return false;\n });\n }\n \n private checkFileRead(capabilities: PluginCapability[], _path: string): boolean {\n // Check if plugin has capability to read this file\n return capabilities.some(cap => {\n const protocolId = cap.protocol.id;\n \n // Check for file read capability\n if (protocolId.includes('protocol.filesystem.read')) {\n // TODO: Add path pattern matching\n return true;\n }\n \n return false;\n });\n }\n \n private checkFileWrite(capabilities: PluginCapability[], _path: string): boolean {\n // Check if plugin has capability to write this file\n return capabilities.some(cap => {\n const protocolId = cap.protocol.id;\n \n // Check for file write capability\n if (protocolId.includes('protocol.filesystem.write')) {\n // TODO: Add path pattern matching\n return true;\n }\n \n return false;\n });\n }\n \n private checkNetworkAccess(capabilities: PluginCapability[], _url: string): boolean {\n // Check if plugin has capability to access this URL\n return capabilities.some(cap => {\n const protocolId = cap.protocol.id;\n \n // Check for network capability\n if (protocolId.includes('protocol.network')) {\n // TODO: Add URL pattern matching\n return true;\n }\n \n return false;\n });\n }\n}\n\n/**\n * Secure Plugin Context\n * Wraps PluginContext with permission checks\n */\nexport class SecurePluginContext implements PluginContext {\n constructor(\n private pluginName: string,\n private permissionEnforcer: PluginPermissionEnforcer,\n private baseContext: PluginContext\n ) {}\n \n registerService(name: string, service: any): void {\n // No permission check for service registration (handled during init)\n this.baseContext.registerService(name, service);\n }\n \n getService<T>(name: string): T {\n // Check permission before accessing service\n this.permissionEnforcer.enforceServiceAccess(this.pluginName, name);\n return this.baseContext.getService<T>(name);\n }\n \n getServices(): Map<string, any> {\n // Return all services (no permission check for listing)\n return this.baseContext.getServices();\n }\n \n hook(name: string, handler: (...args: any[]) => void | Promise<void>): void {\n // No permission check for registering hooks (handled during init)\n this.baseContext.hook(name, handler);\n }\n \n async trigger(name: string, ...args: any[]): Promise<void> {\n // Check permission before triggering hook\n this.permissionEnforcer.enforceHookTrigger(this.pluginName, name);\n await this.baseContext.trigger(name, ...args);\n }\n \n get logger() {\n return this.baseContext.logger;\n }\n \n getKernel() {\n return this.baseContext.getKernel();\n }\n}\n\n/**\n * Create a plugin permission enforcer\n * \n * @param logger - Logger instance\n * @returns Plugin permission enforcer\n */\nexport function createPluginPermissionEnforcer(logger: Logger): PluginPermissionEnforcer {\n return new PluginPermissionEnforcer(logger);\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { \n Permission,\n PermissionSet,\n PermissionAction,\n ResourceType\n} from '@objectstack/spec/kernel';\nimport type { ObjectLogger } from '../logger.js';\n\n/**\n * Permission Grant\n * Represents a granted permission at runtime\n */\nexport interface PermissionGrant {\n permissionId: string;\n pluginId: string;\n grantedAt: Date;\n grantedBy?: string;\n expiresAt?: Date;\n conditions?: Record<string, any>;\n}\n\n/**\n * Permission Check Result\n */\nexport interface PermissionCheckResult {\n allowed: boolean;\n reason?: string;\n requiredPermission?: string;\n grantedPermissions?: string[];\n}\n\n/**\n * Plugin Permission Manager\n * \n * Manages fine-grained permissions for plugin security and access control\n */\nexport class PluginPermissionManager {\n private logger: ObjectLogger;\n \n // Plugin permission definitions\n private permissionSets = new Map<string, PermissionSet>();\n \n // Granted permissions (pluginId -> Set of permission IDs)\n private grants = new Map<string, Set<string>>();\n \n // Permission grant details\n private grantDetails = new Map<string, PermissionGrant>();\n\n constructor(logger: ObjectLogger) {\n this.logger = logger.child({ component: 'PermissionManager' });\n }\n\n /**\n * Register permission requirements for a plugin\n */\n registerPermissions(pluginId: string, permissionSet: PermissionSet): void {\n this.permissionSets.set(pluginId, permissionSet);\n \n this.logger.info('Permissions registered for plugin', { \n pluginId,\n permissionCount: permissionSet.permissions.length\n });\n }\n\n /**\n * Grant a permission to a plugin\n */\n grantPermission(\n pluginId: string,\n permissionId: string,\n grantedBy?: string,\n expiresAt?: Date\n ): void {\n // Verify permission exists in plugin's declared permissions\n const permissionSet = this.permissionSets.get(pluginId);\n if (!permissionSet) {\n throw new Error(`No permissions registered for plugin: ${pluginId}`);\n }\n\n const permission = permissionSet.permissions.find(p => p.id === permissionId);\n if (!permission) {\n throw new Error(`Permission ${permissionId} not declared by plugin ${pluginId}`);\n }\n\n // Create grant\n if (!this.grants.has(pluginId)) {\n this.grants.set(pluginId, new Set());\n }\n this.grants.get(pluginId)!.add(permissionId);\n\n // Store grant details\n const grantKey = `${pluginId}:${permissionId}`;\n this.grantDetails.set(grantKey, {\n permissionId,\n pluginId,\n grantedAt: new Date(),\n grantedBy,\n expiresAt,\n });\n\n this.logger.info('Permission granted', { \n pluginId, \n permissionId,\n grantedBy \n });\n }\n\n /**\n * Revoke a permission from a plugin\n */\n revokePermission(pluginId: string, permissionId: string): void {\n const grants = this.grants.get(pluginId);\n if (grants) {\n grants.delete(permissionId);\n \n const grantKey = `${pluginId}:${permissionId}`;\n this.grantDetails.delete(grantKey);\n\n this.logger.info('Permission revoked', { pluginId, permissionId });\n }\n }\n\n /**\n * Grant all permissions for a plugin\n */\n grantAllPermissions(pluginId: string, grantedBy?: string): void {\n const permissionSet = this.permissionSets.get(pluginId);\n if (!permissionSet) {\n throw new Error(`No permissions registered for plugin: ${pluginId}`);\n }\n\n for (const permission of permissionSet.permissions) {\n this.grantPermission(pluginId, permission.id, grantedBy);\n }\n\n this.logger.info('All permissions granted', { pluginId, grantedBy });\n }\n\n /**\n * Check if a plugin has a specific permission\n */\n hasPermission(pluginId: string, permissionId: string): boolean {\n const grants = this.grants.get(pluginId);\n if (!grants) {\n return false;\n }\n\n // Check if granted\n if (!grants.has(permissionId)) {\n return false;\n }\n\n // Check expiration\n const grantKey = `${pluginId}:${permissionId}`;\n const grantDetails = this.grantDetails.get(grantKey);\n if (grantDetails?.expiresAt && grantDetails.expiresAt < new Date()) {\n this.revokePermission(pluginId, permissionId);\n return false;\n }\n\n return true;\n }\n\n /**\n * Check if plugin can perform an action on a resource\n */\n checkAccess(\n pluginId: string,\n resource: ResourceType,\n action: PermissionAction,\n resourceId?: string\n ): PermissionCheckResult {\n const permissionSet = this.permissionSets.get(pluginId);\n if (!permissionSet) {\n return {\n allowed: false,\n reason: 'No permissions registered for plugin',\n };\n }\n\n // Find matching permissions\n const matchingPermissions = permissionSet.permissions.filter(p => {\n // Check resource type\n if (p.resource !== resource) {\n return false;\n }\n\n // Check action\n if (!p.actions.includes(action)) {\n return false;\n }\n\n // Check resource filter if specified\n if (resourceId && p.filter?.resourceIds) {\n if (!p.filter.resourceIds.includes(resourceId)) {\n return false;\n }\n }\n\n return true;\n });\n\n if (matchingPermissions.length === 0) {\n return {\n allowed: false,\n reason: `No permission found for ${action} on ${resource}`,\n };\n }\n\n // Check if any matching permission is granted\n const grantedPermissions = matchingPermissions.filter(p => \n this.hasPermission(pluginId, p.id)\n );\n\n if (grantedPermissions.length === 0) {\n return {\n allowed: false,\n reason: 'Required permissions not granted',\n requiredPermission: matchingPermissions[0].id,\n };\n }\n\n return {\n allowed: true,\n grantedPermissions: grantedPermissions.map(p => p.id),\n };\n }\n\n /**\n * Get all permissions for a plugin\n */\n getPluginPermissions(pluginId: string): Permission[] {\n const permissionSet = this.permissionSets.get(pluginId);\n return permissionSet?.permissions || [];\n }\n\n /**\n * Get granted permissions for a plugin\n */\n getGrantedPermissions(pluginId: string): string[] {\n const grants = this.grants.get(pluginId);\n return grants ? Array.from(grants) : [];\n }\n\n /**\n * Get required but not granted permissions\n */\n getMissingPermissions(pluginId: string): Permission[] {\n const permissionSet = this.permissionSets.get(pluginId);\n if (!permissionSet) {\n return [];\n }\n\n const granted = this.grants.get(pluginId) || new Set();\n \n return permissionSet.permissions.filter(p => \n p.required && !granted.has(p.id)\n );\n }\n\n /**\n * Check if all required permissions are granted\n */\n hasAllRequiredPermissions(pluginId: string): boolean {\n return this.getMissingPermissions(pluginId).length === 0;\n }\n\n /**\n * Get permission grant details\n */\n getGrantDetails(pluginId: string, permissionId: string): PermissionGrant | undefined {\n const grantKey = `${pluginId}:${permissionId}`;\n return this.grantDetails.get(grantKey);\n }\n\n /**\n * Validate permission against scope constraints\n */\n validatePermissionScope(\n permission: Permission,\n context: {\n tenantId?: string;\n userId?: string;\n resourceId?: string;\n }\n ): boolean {\n switch (permission.scope) {\n case 'global':\n return true;\n\n case 'tenant':\n return !!context.tenantId;\n\n case 'user':\n return !!context.userId;\n\n case 'resource':\n return !!context.resourceId;\n\n case 'plugin':\n return true;\n\n default:\n return false;\n }\n }\n\n /**\n * Clear all permissions for a plugin\n */\n clearPluginPermissions(pluginId: string): void {\n this.permissionSets.delete(pluginId);\n \n const grants = this.grants.get(pluginId);\n if (grants) {\n for (const permissionId of grants) {\n const grantKey = `${pluginId}:${permissionId}`;\n this.grantDetails.delete(grantKey);\n }\n this.grants.delete(pluginId);\n }\n\n this.logger.info('All permissions cleared', { pluginId });\n }\n\n /**\n * Shutdown permission manager\n */\n shutdown(): void {\n this.permissionSets.clear();\n this.grants.clear();\n this.grantDetails.clear();\n \n this.logger.info('Permission manager shutdown complete');\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { \n SandboxConfig\n} from '@objectstack/spec/kernel';\nimport type { ObjectLogger } from '../logger.js';\nimport { getMemoryUsage } from '../utils/env.js';\n\n/**\n * Resource Usage Statistics\n */\nexport interface ResourceUsage {\n memory: {\n current: number;\n peak: number;\n limit?: number;\n };\n cpu: {\n current: number;\n average: number;\n limit?: number;\n };\n connections: {\n current: number;\n limit?: number;\n };\n}\n\n/**\n * Sandbox Execution Context\n * Represents an isolated execution environment for a plugin\n */\nexport interface SandboxContext {\n pluginId: string;\n config: SandboxConfig;\n startTime: Date;\n resourceUsage: ResourceUsage;\n}\n\n/**\n * Plugin Sandbox Runtime\n * \n * Provides isolated execution environments for plugins with resource limits\n * and access controls\n */\nexport class PluginSandboxRuntime {\n private logger: ObjectLogger;\n \n // Active sandboxes (pluginId -> context)\n private sandboxes = new Map<string, SandboxContext>();\n \n // Resource monitoring intervals\n private monitoringIntervals = new Map<string, NodeJS.Timeout>();\n\n constructor(logger: ObjectLogger) {\n this.logger = logger.child({ component: 'SandboxRuntime' });\n }\n\n /**\n * Create a sandbox for a plugin\n */\n createSandbox(pluginId: string, config: SandboxConfig): SandboxContext {\n if (this.sandboxes.has(pluginId)) {\n throw new Error(`Sandbox already exists for plugin: ${pluginId}`);\n }\n\n const context: SandboxContext = {\n pluginId,\n config,\n startTime: new Date(),\n resourceUsage: {\n memory: { current: 0, peak: 0, limit: config.memory?.maxHeap },\n cpu: { current: 0, average: 0, limit: config.cpu?.maxCpuPercent },\n connections: { current: 0, limit: config.network?.maxConnections },\n },\n };\n\n this.sandboxes.set(pluginId, context);\n\n // Start resource monitoring\n this.startResourceMonitoring(pluginId);\n\n this.logger.info('Sandbox created', { \n pluginId,\n level: config.level,\n memoryLimit: config.memory?.maxHeap,\n cpuLimit: config.cpu?.maxCpuPercent\n });\n\n return context;\n }\n\n /**\n * Destroy a sandbox\n */\n destroySandbox(pluginId: string): void {\n const context = this.sandboxes.get(pluginId);\n if (!context) {\n return;\n }\n\n // Stop monitoring\n this.stopResourceMonitoring(pluginId);\n\n this.sandboxes.delete(pluginId);\n\n this.logger.info('Sandbox destroyed', { pluginId });\n }\n\n /**\n * Check if resource access is allowed\n */\n checkResourceAccess(\n pluginId: string,\n resourceType: 'file' | 'network' | 'process' | 'env',\n resourcePath?: string\n ): { allowed: boolean; reason?: string } {\n const context = this.sandboxes.get(pluginId);\n if (!context) {\n return { allowed: false, reason: 'Sandbox not found' };\n }\n\n const { config } = context;\n\n switch (resourceType) {\n case 'file':\n return this.checkFileAccess(config, resourcePath);\n \n case 'network':\n return this.checkNetworkAccess(config, resourcePath);\n \n case 'process':\n return this.checkProcessAccess(config);\n \n case 'env':\n return this.checkEnvAccess(config, resourcePath);\n \n default:\n return { allowed: false, reason: 'Unknown resource type' };\n }\n }\n\n /**\n * Check file system access\n * WARNING: Uses simple prefix matching. For production, use proper path\n * resolution with path.resolve() and path.normalize() to prevent traversal.\n */\n private checkFileAccess(\n config: SandboxConfig,\n path?: string\n ): { allowed: boolean; reason?: string } {\n if (config.level === 'none') {\n return { allowed: true };\n }\n\n if (!config.filesystem) {\n return { allowed: false, reason: 'File system access not configured' };\n }\n\n // If no path specified, check general access\n if (!path) {\n return { allowed: config.filesystem.mode !== 'none' };\n }\n\n // TODO: Use path.resolve() and path.normalize() for production\n // Check allowed paths\n const allowedPaths = config.filesystem.allowedPaths || [];\n const isAllowed = allowedPaths.some(allowed => {\n // Simple prefix matching - vulnerable to traversal attacks\n // TODO: Use proper path resolution\n return path.startsWith(allowed);\n });\n\n if (allowedPaths.length > 0 && !isAllowed) {\n return { \n allowed: false, \n reason: `Path not in allowed list: ${path}` \n };\n }\n\n // Check denied paths\n const deniedPaths = config.filesystem.deniedPaths || [];\n const isDenied = deniedPaths.some(denied => {\n return path.startsWith(denied);\n });\n\n if (isDenied) {\n return { \n allowed: false, \n reason: `Path is explicitly denied: ${path}` \n };\n }\n\n return { allowed: true };\n }\n\n /**\n * Check network access\n * WARNING: Uses simple string matching. For production, use proper URL\n * parsing with new URL() and check hostname property.\n */\n private checkNetworkAccess(\n config: SandboxConfig,\n url?: string\n ): { allowed: boolean; reason?: string } {\n if (config.level === 'none') {\n return { allowed: true };\n }\n\n if (!config.network) {\n return { allowed: false, reason: 'Network access not configured' };\n }\n\n // Check if network access is enabled\n if (config.network.mode === 'none') {\n return { allowed: false, reason: 'Network access disabled' };\n }\n\n // If no URL specified, check general access\n if (!url) {\n return { allowed: (config.network.mode as string) !== 'none' };\n }\n\n // TODO: Use new URL() and check hostname property for production\n // Check allowed hosts\n const allowedHosts = config.network.allowedHosts || [];\n if (allowedHosts.length > 0) {\n const isAllowed = allowedHosts.some(host => {\n // Simple string matching - vulnerable to bypass\n // TODO: Use proper URL parsing\n return url.includes(host);\n });\n\n if (!isAllowed) {\n return { \n allowed: false, \n reason: `Host not in allowed list: ${url}` \n };\n }\n }\n\n // Check denied hosts\n const deniedHosts = config.network.deniedHosts || [];\n const isDenied = deniedHosts.some(host => {\n return url.includes(host);\n });\n\n if (isDenied) {\n return { \n allowed: false, \n reason: `Host is blocked: ${url}` \n };\n }\n\n return { allowed: true };\n }\n\n /**\n * Check process spawning access\n */\n private checkProcessAccess(\n config: SandboxConfig\n ): { allowed: boolean; reason?: string } {\n if (config.level === 'none') {\n return { allowed: true };\n }\n\n if (!config.process) {\n return { allowed: false, reason: 'Process access not configured' };\n }\n\n if (!config.process.allowSpawn) {\n return { allowed: false, reason: 'Process spawning not allowed' };\n }\n\n return { allowed: true };\n }\n\n /**\n * Check environment variable access\n */\n private checkEnvAccess(\n config: SandboxConfig,\n varName?: string\n ): { allowed: boolean; reason?: string } {\n if (config.level === 'none') {\n return { allowed: true };\n }\n\n if (!config.process) {\n return { allowed: false, reason: 'Environment access not configured' };\n }\n\n // If no variable specified, check general access\n if (!varName) {\n return { allowed: true };\n }\n\n // For now, allow all env access if process is configured\n // In a real implementation, would check specific allowed vars\n return { allowed: true };\n }\n\n /**\n * Check resource limits\n */\n checkResourceLimits(pluginId: string): { \n withinLimits: boolean; \n violations: string[] \n } {\n const context = this.sandboxes.get(pluginId);\n if (!context) {\n return { withinLimits: true, violations: [] };\n }\n\n const violations: string[] = [];\n const { resourceUsage, config } = context;\n\n // Check memory limit\n if (config.memory?.maxHeap && \n resourceUsage.memory.current > config.memory.maxHeap) {\n violations.push(`Memory limit exceeded: ${resourceUsage.memory.current} > ${config.memory.maxHeap}`);\n }\n\n // Check CPU limit (would need runtime config)\n if (config.runtime?.resourceLimits?.maxCpu && \n resourceUsage.cpu.current > config.runtime.resourceLimits.maxCpu) {\n violations.push(`CPU limit exceeded: ${resourceUsage.cpu.current}% > ${config.runtime.resourceLimits.maxCpu}%`);\n }\n\n // Check connection limit\n if (config.network?.maxConnections && \n resourceUsage.connections.current > config.network.maxConnections) {\n violations.push(`Connection limit exceeded: ${resourceUsage.connections.current} > ${config.network.maxConnections}`);\n }\n\n return {\n withinLimits: violations.length === 0,\n violations,\n };\n }\n\n /**\n * Get resource usage for a plugin\n */\n getResourceUsage(pluginId: string): ResourceUsage | undefined {\n const context = this.sandboxes.get(pluginId);\n return context?.resourceUsage;\n }\n\n /**\n * Start monitoring resource usage\n */\n private startResourceMonitoring(pluginId: string): void {\n // Monitor every 5 seconds\n const interval = setInterval(() => {\n this.updateResourceUsage(pluginId);\n }, 5000);\n\n this.monitoringIntervals.set(pluginId, interval);\n }\n\n /**\n * Stop monitoring resource usage\n */\n private stopResourceMonitoring(pluginId: string): void {\n const interval = this.monitoringIntervals.get(pluginId);\n if (interval) {\n clearInterval(interval);\n this.monitoringIntervals.delete(pluginId);\n }\n }\n\n /**\n * Update resource usage statistics\n * \n * NOTE: Currently uses global process.memoryUsage() which tracks the entire\n * Node.js process, not individual plugins. For production, implement proper\n * per-plugin tracking using V8 heap snapshots or allocation tracking at\n * plugin boundaries.\n */\n private updateResourceUsage(pluginId: string): void {\n const context = this.sandboxes.get(pluginId);\n if (!context) {\n return;\n }\n\n // In a real implementation, this would collect actual metrics\n // For now, this is a placeholder structure\n \n // Update memory usage (global process memory - not per-plugin)\n // TODO: Implement per-plugin memory tracking\n const memoryUsage = getMemoryUsage();\n context.resourceUsage.memory.current = memoryUsage.heapUsed;\n context.resourceUsage.memory.peak = Math.max(\n context.resourceUsage.memory.peak,\n memoryUsage.heapUsed\n );\n\n // Update CPU usage (would use process.cpuUsage() or similar)\n // This is a placeholder - real implementation would track per-plugin CPU\n // TODO: Implement per-plugin CPU tracking\n context.resourceUsage.cpu.current = 0;\n\n // Check for violations\n const { withinLimits, violations } = this.checkResourceLimits(pluginId);\n if (!withinLimits) {\n this.logger.warn('Resource limit violations detected', { \n pluginId, \n violations \n });\n }\n }\n\n /**\n * Get all active sandboxes\n */\n getAllSandboxes(): Map<string, SandboxContext> {\n return new Map(this.sandboxes);\n }\n\n /**\n * Shutdown sandbox runtime\n */\n shutdown(): void {\n // Stop all monitoring\n for (const pluginId of this.monitoringIntervals.keys()) {\n this.stopResourceMonitoring(pluginId);\n }\n\n this.sandboxes.clear();\n \n this.logger.info('Sandbox runtime shutdown complete');\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { \n KernelSecurityVulnerability,\n KernelSecurityScanResult\n} from '@objectstack/spec/kernel';\nimport type { ObjectLogger } from '../logger.js';\n\n/**\n * Scan Target\n */\nexport interface ScanTarget {\n pluginId: string;\n version: string;\n files?: string[];\n dependencies?: Record<string, string>;\n}\n\n/**\n * Security Issue\n */\nexport interface SecurityIssue {\n id: string;\n severity: 'critical' | 'high' | 'medium' | 'low' | 'info';\n category: 'vulnerability' | 'malware' | 'license' | 'code-quality' | 'configuration';\n title: string;\n description: string;\n location?: {\n file?: string;\n line?: number;\n column?: number;\n };\n remediation?: string;\n cve?: string;\n cvss?: number;\n}\n\n/**\n * Plugin Security Scanner\n * \n * Scans plugins for security vulnerabilities, malware, and license issues\n */\nexport class PluginSecurityScanner {\n private logger: ObjectLogger;\n \n // Known vulnerabilities database (CVE cache)\n private vulnerabilityDb = new Map<string, KernelSecurityVulnerability>();\n \n // Scan results cache\n private scanResults = new Map<string, KernelSecurityScanResult>();\n\n private passThreshold: number = 70;\n\n constructor(logger: ObjectLogger, config?: { passThreshold?: number }) {\n this.logger = logger.child({ component: 'SecurityScanner' });\n if (config?.passThreshold !== undefined) {\n this.passThreshold = config.passThreshold;\n }\n }\n\n /**\n * Perform a comprehensive security scan on a plugin\n */\n async scan(target: ScanTarget): Promise<KernelSecurityScanResult> {\n this.logger.info('Starting security scan', { \n pluginId: target.pluginId,\n version: target.version \n });\n\n const issues: SecurityIssue[] = [];\n\n try {\n // 1. Scan for code vulnerabilities\n const codeIssues = await this.scanCode(target);\n issues.push(...codeIssues);\n\n // 2. Scan dependencies for known vulnerabilities\n const depIssues = await this.scanDependencies(target);\n issues.push(...depIssues);\n\n // 3. Scan for malware patterns\n const malwareIssues = await this.scanMalware(target);\n issues.push(...malwareIssues);\n\n // 4. Check license compliance\n const licenseIssues = await this.scanLicenses(target);\n issues.push(...licenseIssues);\n\n // 5. Check configuration security\n const configIssues = await this.scanConfiguration(target);\n issues.push(...configIssues);\n\n // Calculate security score (0-100, higher is better)\n const score = this.calculateSecurityScore(issues);\n\n const result: KernelSecurityScanResult = {\n timestamp: new Date().toISOString(),\n scanner: { name: 'ObjectStack Security Scanner', version: '1.0.0' },\n status: score >= this.passThreshold ? 'passed' : 'failed',\n vulnerabilities: issues.map(issue => ({\n id: issue.id,\n severity: issue.severity,\n category: issue.category,\n title: issue.title,\n description: issue.description,\n location: issue.location ? `${issue.location.file}:${issue.location.line}` : undefined,\n remediation: issue.remediation,\n affectedVersions: [],\n exploitAvailable: false,\n patchAvailable: false,\n })),\n summary: {\n totalVulnerabilities: issues.length,\n criticalCount: issues.filter(i => i.severity === 'critical').length,\n highCount: issues.filter(i => i.severity === 'high').length,\n mediumCount: issues.filter(i => i.severity === 'medium').length,\n lowCount: issues.filter(i => i.severity === 'low').length,\n infoCount: issues.filter(i => i.severity === 'info').length,\n },\n };\n\n this.scanResults.set(`${target.pluginId}:${target.version}`, result);\n\n this.logger.info('Security scan complete', { \n pluginId: target.pluginId,\n score,\n status: result.status,\n summary: result.summary\n });\n\n return result;\n } catch (error) {\n this.logger.error('Security scan failed', { \n pluginId: target.pluginId, \n error \n });\n\n throw error;\n }\n }\n\n /**\n * Scan code for vulnerabilities\n */\n private async scanCode(target: ScanTarget): Promise<SecurityIssue[]> {\n const issues: SecurityIssue[] = [];\n\n // In a real implementation, this would:\n // - Parse code with AST (e.g., using @typescript-eslint/parser)\n // - Check for dangerous patterns (eval, Function constructor, etc.)\n // - Check for XSS vulnerabilities\n // - Check for SQL injection patterns\n // - Check for insecure crypto usage\n // - Check for path traversal vulnerabilities\n\n this.logger.debug('Code scan complete', { \n pluginId: target.pluginId,\n issuesFound: issues.length \n });\n\n return issues;\n }\n\n /**\n * Scan dependencies for known vulnerabilities\n */\n private async scanDependencies(target: ScanTarget): Promise<SecurityIssue[]> {\n const issues: SecurityIssue[] = [];\n\n if (!target.dependencies) {\n return issues;\n }\n\n // In a real implementation, this would:\n // - Query npm audit API\n // - Check GitHub Advisory Database\n // - Check Snyk vulnerability database\n // - Check OSV (Open Source Vulnerabilities)\n\n for (const [depName, version] of Object.entries(target.dependencies)) {\n const vulnKey = `${depName}@${version}`;\n const vulnerability = this.vulnerabilityDb.get(vulnKey);\n\n if (vulnerability) {\n issues.push({\n id: `vuln-${vulnerability.cve || depName}`,\n severity: vulnerability.severity,\n category: 'vulnerability',\n title: `Vulnerable dependency: ${depName}`,\n description: `${depName}@${version} has known security vulnerabilities`,\n remediation: vulnerability.fixedIn \n ? `Upgrade to ${vulnerability.fixedIn.join(' or ')}`\n : 'No fix available',\n cve: vulnerability.cve,\n });\n }\n }\n\n this.logger.debug('Dependency scan complete', { \n pluginId: target.pluginId,\n dependencies: Object.keys(target.dependencies).length,\n vulnerabilities: issues.length \n });\n\n return issues;\n }\n\n /**\n * Scan for malware patterns\n */\n private async scanMalware(target: ScanTarget): Promise<SecurityIssue[]> {\n const issues: SecurityIssue[] = [];\n\n // In a real implementation, this would:\n // - Check for obfuscated code\n // - Check for suspicious network activity patterns\n // - Check for crypto mining patterns\n // - Check for data exfiltration patterns\n // - Use ML-based malware detection\n // - Check file hashes against known malware databases\n\n this.logger.debug('Malware scan complete', { \n pluginId: target.pluginId,\n issuesFound: issues.length \n });\n\n return issues;\n }\n\n /**\n * Check license compliance\n */\n private async scanLicenses(target: ScanTarget): Promise<SecurityIssue[]> {\n const issues: SecurityIssue[] = [];\n\n if (!target.dependencies) {\n return issues;\n }\n\n // In a real implementation, this would:\n // - Check license compatibility\n // - Detect GPL contamination\n // - Flag proprietary dependencies\n // - Check for missing licenses\n // - Verify SPDX identifiers\n\n this.logger.debug('License scan complete', { \n pluginId: target.pluginId,\n issuesFound: issues.length \n });\n\n return issues;\n }\n\n /**\n * Check configuration security\n */\n private async scanConfiguration(target: ScanTarget): Promise<SecurityIssue[]> {\n const issues: SecurityIssue[] = [];\n\n // In a real implementation, this would:\n // - Check for hardcoded secrets\n // - Check for weak permissions\n // - Check for insecure defaults\n // - Check for missing security headers\n // - Check CSP policies\n\n this.logger.debug('Configuration scan complete', { \n pluginId: target.pluginId,\n issuesFound: issues.length \n });\n\n return issues;\n }\n\n /**\n * Calculate security score based on issues\n */\n private calculateSecurityScore(issues: SecurityIssue[]): number {\n // Start with perfect score\n let score = 100;\n\n // Deduct points based on severity\n for (const issue of issues) {\n switch (issue.severity) {\n case 'critical':\n score -= 20;\n break;\n case 'high':\n score -= 10;\n break;\n case 'medium':\n score -= 5;\n break;\n case 'low':\n score -= 2;\n break;\n case 'info':\n score -= 0;\n break;\n }\n }\n\n // Ensure score doesn't go below 0\n return Math.max(0, score);\n }\n\n /**\n * Add a vulnerability to the database\n */\n addVulnerability(\n packageName: string,\n version: string,\n vulnerability: KernelSecurityVulnerability\n ): void {\n const key = `${packageName}@${version}`;\n this.vulnerabilityDb.set(key, vulnerability);\n \n this.logger.debug('Vulnerability added to database', { \n package: packageName, \n version,\n cve: vulnerability.cve \n });\n }\n\n /**\n * Get scan result from cache\n */\n getScanResult(pluginId: string, version: string): KernelSecurityScanResult | undefined {\n return this.scanResults.get(`${pluginId}:${version}`);\n }\n\n /**\n * Clear scan results cache\n */\n clearCache(): void {\n this.scanResults.clear();\n this.logger.debug('Scan results cache cleared');\n }\n\n /**\n * Update vulnerability database from external source\n */\n async updateVulnerabilityDatabase(): Promise<void> {\n this.logger.info('Updating vulnerability database');\n\n // In a real implementation, this would:\n // - Fetch from GitHub Advisory Database\n // - Fetch from npm audit\n // - Fetch from NVD (National Vulnerability Database)\n // - Parse and cache vulnerability data\n\n this.logger.info('Vulnerability database updated', { \n entries: this.vulnerabilityDb.size \n });\n }\n\n /**\n * Shutdown security scanner\n */\n shutdown(): void {\n this.vulnerabilityDb.clear();\n this.scanResults.clear();\n \n this.logger.info('Security scanner shutdown complete');\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { \n PluginHealthStatus, \n PluginHealthCheck, \n PluginHealthReport \n} from '@objectstack/spec/kernel';\nimport type { ObjectLogger } from './logger.js';\nimport type { Plugin } from './types.js';\n\n/**\n * Plugin Health Monitor\n * \n * Monitors plugin health status and performs automatic recovery actions.\n * Implements the advanced lifecycle health monitoring protocol.\n */\nexport class PluginHealthMonitor {\n private logger: ObjectLogger;\n private healthChecks = new Map<string, PluginHealthCheck>();\n private healthStatus = new Map<string, PluginHealthStatus>();\n private healthReports = new Map<string, PluginHealthReport>();\n private checkIntervals = new Map<string, NodeJS.Timeout>();\n private failureCounters = new Map<string, number>();\n private successCounters = new Map<string, number>();\n private restartAttempts = new Map<string, number>();\n\n constructor(logger: ObjectLogger) {\n this.logger = logger.child({ component: 'HealthMonitor' });\n }\n\n /**\n * Register a plugin for health monitoring\n */\n registerPlugin(pluginName: string, config: PluginHealthCheck): void {\n this.healthChecks.set(pluginName, config);\n this.healthStatus.set(pluginName, 'unknown');\n this.failureCounters.set(pluginName, 0);\n this.successCounters.set(pluginName, 0);\n this.restartAttempts.set(pluginName, 0);\n\n this.logger.info('Plugin registered for health monitoring', { \n plugin: pluginName,\n interval: config.interval \n });\n }\n\n /**\n * Start monitoring a plugin\n */\n startMonitoring(pluginName: string, plugin: Plugin): void {\n const config = this.healthChecks.get(pluginName);\n if (!config) {\n this.logger.warn('Cannot start monitoring - plugin not registered', { plugin: pluginName });\n return;\n }\n\n // Clear any existing interval\n this.stopMonitoring(pluginName);\n\n // Set up periodic health checks\n const interval = setInterval(() => {\n this.performHealthCheck(pluginName, plugin, config).catch(error => {\n this.logger.error('Health check failed with error', { \n plugin: pluginName, \n error \n });\n });\n }, config.interval);\n\n this.checkIntervals.set(pluginName, interval);\n this.logger.info('Health monitoring started', { plugin: pluginName });\n\n // Perform initial health check\n this.performHealthCheck(pluginName, plugin, config).catch(error => {\n this.logger.error('Initial health check failed', { \n plugin: pluginName, \n error \n });\n });\n }\n\n /**\n * Stop monitoring a plugin\n */\n stopMonitoring(pluginName: string): void {\n const interval = this.checkIntervals.get(pluginName);\n if (interval) {\n clearInterval(interval);\n this.checkIntervals.delete(pluginName);\n this.logger.info('Health monitoring stopped', { plugin: pluginName });\n }\n }\n\n /**\n * Perform a health check on a plugin\n */\n private async performHealthCheck(\n pluginName: string,\n plugin: Plugin,\n config: PluginHealthCheck\n ): Promise<void> {\n const startTime = Date.now();\n let status: PluginHealthStatus = 'healthy';\n let message: string | undefined;\n const checks: Array<{ name: string; status: 'passed' | 'failed' | 'warning'; message?: string }> = [];\n\n try {\n // Check if plugin has a custom health check method\n if (config.checkMethod && typeof (plugin as any)[config.checkMethod] === 'function') {\n const checkResult = await Promise.race([\n (plugin as any)[config.checkMethod](),\n this.timeout(config.timeout, `Health check timeout after ${config.timeout}ms`)\n ]);\n\n if (checkResult === false || (checkResult && checkResult.status === 'unhealthy')) {\n status = 'unhealthy';\n message = checkResult?.message || 'Custom health check failed';\n checks.push({ name: config.checkMethod, status: 'failed', message });\n } else {\n checks.push({ name: config.checkMethod, status: 'passed' });\n }\n } else {\n // Default health check - just verify plugin is loaded\n checks.push({ name: 'plugin-loaded', status: 'passed' });\n }\n\n // Update counters based on result\n if (status === 'healthy') {\n this.successCounters.set(pluginName, (this.successCounters.get(pluginName) || 0) + 1);\n this.failureCounters.set(pluginName, 0);\n\n // Recover from unhealthy state if we have enough successes\n const currentStatus = this.healthStatus.get(pluginName);\n if (currentStatus === 'unhealthy' || currentStatus === 'degraded') {\n const successCount = this.successCounters.get(pluginName) || 0;\n if (successCount >= config.successThreshold) {\n this.healthStatus.set(pluginName, 'healthy');\n this.logger.info('Plugin recovered to healthy state', { plugin: pluginName });\n } else {\n this.healthStatus.set(pluginName, 'recovering');\n }\n } else {\n this.healthStatus.set(pluginName, 'healthy');\n }\n } else {\n this.failureCounters.set(pluginName, (this.failureCounters.get(pluginName) || 0) + 1);\n this.successCounters.set(pluginName, 0);\n\n const failureCount = this.failureCounters.get(pluginName) || 0;\n if (failureCount >= config.failureThreshold) {\n this.healthStatus.set(pluginName, 'unhealthy');\n this.logger.warn('Plugin marked as unhealthy', { \n plugin: pluginName, \n failures: failureCount \n });\n\n // Attempt auto-restart if configured\n if (config.autoRestart) {\n await this.attemptRestart(pluginName, plugin, config);\n }\n } else {\n this.healthStatus.set(pluginName, 'degraded');\n }\n }\n } catch (error) {\n status = 'failed';\n message = error instanceof Error ? error.message : 'Unknown error';\n this.failureCounters.set(pluginName, (this.failureCounters.get(pluginName) || 0) + 1);\n this.healthStatus.set(pluginName, 'failed');\n \n checks.push({ \n name: 'health-check', \n status: 'failed', \n message: message \n });\n\n this.logger.error('Health check exception', { \n plugin: pluginName, \n error \n });\n }\n\n // Create health report\n const report: PluginHealthReport = {\n status: this.healthStatus.get(pluginName) || 'unknown',\n timestamp: new Date().toISOString(),\n message,\n metrics: {\n uptime: Date.now() - startTime,\n },\n checks: checks.length > 0 ? checks : undefined,\n };\n\n this.healthReports.set(pluginName, report);\n }\n\n /**\n * Attempt to restart a plugin\n */\n private async attemptRestart(\n pluginName: string,\n plugin: Plugin,\n config: PluginHealthCheck\n ): Promise<void> {\n const attempts = this.restartAttempts.get(pluginName) || 0;\n \n if (attempts >= config.maxRestartAttempts) {\n this.logger.error('Max restart attempts reached, giving up', { \n plugin: pluginName, \n attempts \n });\n this.healthStatus.set(pluginName, 'failed');\n return;\n }\n\n this.restartAttempts.set(pluginName, attempts + 1);\n \n // Calculate backoff delay\n const delay = this.calculateBackoff(attempts, config.restartBackoff);\n \n this.logger.info('Scheduling plugin restart', { \n plugin: pluginName, \n attempt: attempts + 1, \n delay \n });\n\n await new Promise(resolve => setTimeout(resolve, delay));\n\n try {\n // Call destroy and init to restart\n if (plugin.destroy) {\n await plugin.destroy();\n }\n \n // Note: Full restart would require kernel context\n // This is a simplified version - actual implementation would need kernel integration\n this.logger.info('Plugin restarted', { plugin: pluginName });\n \n // Reset counters on successful restart\n this.failureCounters.set(pluginName, 0);\n this.successCounters.set(pluginName, 0);\n this.healthStatus.set(pluginName, 'recovering');\n } catch (error) {\n this.logger.error('Plugin restart failed', { \n plugin: pluginName, \n error \n });\n this.healthStatus.set(pluginName, 'failed');\n }\n }\n\n /**\n * Calculate backoff delay for restarts\n */\n private calculateBackoff(attempt: number, strategy: 'fixed' | 'linear' | 'exponential'): number {\n const baseDelay = 1000; // 1 second base\n\n switch (strategy) {\n case 'fixed':\n return baseDelay;\n case 'linear':\n return baseDelay * (attempt + 1);\n case 'exponential':\n return baseDelay * Math.pow(2, attempt);\n default:\n return baseDelay;\n }\n }\n\n /**\n * Get current health status of a plugin\n */\n getHealthStatus(pluginName: string): PluginHealthStatus | undefined {\n return this.healthStatus.get(pluginName);\n }\n\n /**\n * Get latest health report for a plugin\n */\n getHealthReport(pluginName: string): PluginHealthReport | undefined {\n return this.healthReports.get(pluginName);\n }\n\n /**\n * Get all health statuses\n */\n getAllHealthStatuses(): Map<string, PluginHealthStatus> {\n return new Map(this.healthStatus);\n }\n\n /**\n * Shutdown health monitor\n */\n shutdown(): void {\n // Stop all monitoring intervals\n for (const pluginName of this.checkIntervals.keys()) {\n this.stopMonitoring(pluginName);\n }\n \n this.healthChecks.clear();\n this.healthStatus.clear();\n this.healthReports.clear();\n this.failureCounters.clear();\n this.successCounters.clear();\n this.restartAttempts.clear();\n \n this.logger.info('Health monitor shutdown complete');\n }\n\n /**\n * Timeout helper\n */\n private timeout<T>(ms: number, message: string): Promise<T> {\n return new Promise((_, reject) => {\n setTimeout(() => reject(new Error(message)), ms);\n });\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { \n HotReloadConfig, \n PluginStateSnapshot \n} from '@objectstack/spec/kernel';\nimport type { ObjectLogger } from './logger.js';\nimport type { Plugin } from './types.js';\n\n// Polyfill for UUID generation to support both Node.js and Browser\nconst generateUUID = () => {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n // Basic UUID v4 fallback\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {\n const r = Math.random() * 16 | 0;\n const v = c === 'x' ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n};\n\n/**\n * Plugin State Manager\n * \n * Handles state persistence and restoration during hot reloads\n */\nclass PluginStateManager {\n private logger: ObjectLogger;\n private stateSnapshots = new Map<string, PluginStateSnapshot>();\n private memoryStore = new Map<string, any>();\n\n constructor(logger: ObjectLogger) {\n this.logger = logger.child({ component: 'StateManager' });\n }\n\n /**\n * Save plugin state before reload\n */\n async saveState(\n pluginId: string,\n version: string,\n state: Record<string, any>,\n config: HotReloadConfig\n ): Promise<string> {\n const snapshot: PluginStateSnapshot = {\n pluginId,\n version,\n timestamp: new Date().toISOString(),\n state,\n metadata: {\n checksum: this.calculateChecksum(state),\n compressed: false,\n },\n };\n\n const snapshotId = generateUUID();\n\n switch (config.stateStrategy) {\n case 'memory':\n this.memoryStore.set(snapshotId, snapshot);\n this.logger.debug('State saved to memory', { pluginId, snapshotId });\n break;\n\n case 'disk':\n // For disk storage, we would write to file system\n // For now, store in memory as fallback\n this.memoryStore.set(snapshotId, snapshot);\n this.logger.debug('State saved to disk (memory fallback)', { pluginId, snapshotId });\n break;\n\n case 'distributed':\n // For distributed storage, would use Redis/etcd\n // For now, store in memory as fallback\n this.memoryStore.set(snapshotId, snapshot);\n this.logger.debug('State saved to distributed store (memory fallback)', { \n pluginId, \n snapshotId \n });\n break;\n\n case 'none':\n this.logger.debug('State persistence disabled', { pluginId });\n break;\n }\n\n this.stateSnapshots.set(pluginId, snapshot);\n return snapshotId;\n }\n\n /**\n * Restore plugin state after reload\n */\n async restoreState(\n pluginId: string,\n snapshotId?: string\n ): Promise<Record<string, any> | undefined> {\n // Try to get from snapshot ID first, otherwise use latest for plugin\n let snapshot: PluginStateSnapshot | undefined;\n\n if (snapshotId) {\n snapshot = this.memoryStore.get(snapshotId);\n } else {\n snapshot = this.stateSnapshots.get(pluginId);\n }\n\n if (!snapshot) {\n this.logger.warn('No state snapshot found', { pluginId, snapshotId });\n return undefined;\n }\n\n // Verify checksum if available\n if (snapshot.metadata?.checksum) {\n const currentChecksum = this.calculateChecksum(snapshot.state);\n if (currentChecksum !== snapshot.metadata.checksum) {\n this.logger.error('State checksum mismatch - data may be corrupted', { \n pluginId,\n expected: snapshot.metadata.checksum,\n actual: currentChecksum\n });\n return undefined;\n }\n }\n\n this.logger.debug('State restored', { pluginId, version: snapshot.version });\n return snapshot.state;\n }\n\n /**\n * Clear state for a plugin\n */\n clearState(pluginId: string): void {\n this.stateSnapshots.delete(pluginId);\n // Note: We don't clear memory store as it might have multiple snapshots\n this.logger.debug('State cleared', { pluginId });\n }\n\n /**\n * Calculate simple checksum for state verification\n * WARNING: This is a simple hash for demo purposes.\n * In production, use a cryptographic hash like SHA-256.\n */\n private calculateChecksum(state: Record<string, any>): string {\n // Simple checksum using JSON serialization\n // TODO: Replace with crypto.createHash('sha256') for production\n const stateStr = JSON.stringify(state);\n let hash = 0;\n for (let i = 0; i < stateStr.length; i++) {\n const char = stateStr.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n return hash.toString(16);\n }\n\n /**\n * Shutdown state manager\n */\n shutdown(): void {\n this.stateSnapshots.clear();\n this.memoryStore.clear();\n this.logger.info('State manager shutdown complete');\n }\n}\n\n/**\n * Hot Reload Manager\n * \n * Manages hot reloading of plugins with state preservation\n */\nexport class HotReloadManager {\n private logger: ObjectLogger;\n private stateManager: PluginStateManager;\n private reloadConfigs = new Map<string, HotReloadConfig>();\n private watchHandles = new Map<string, any>();\n private reloadTimers = new Map<string, NodeJS.Timeout>();\n\n constructor(logger: ObjectLogger) {\n this.logger = logger.child({ component: 'HotReload' });\n this.stateManager = new PluginStateManager(logger);\n }\n\n /**\n * Register a plugin for hot reload\n */\n registerPlugin(pluginName: string, config: HotReloadConfig): void {\n if (!config.enabled) {\n this.logger.debug('Hot reload disabled for plugin', { plugin: pluginName });\n return;\n }\n\n this.reloadConfigs.set(pluginName, config);\n this.logger.info('Plugin registered for hot reload', { \n plugin: pluginName,\n watchPatterns: config.watchPatterns,\n stateStrategy: config.stateStrategy\n });\n }\n\n /**\n * Start watching for changes (requires file system integration)\n */\n startWatching(pluginName: string): void {\n const config = this.reloadConfigs.get(pluginName);\n if (!config || !config.enabled) {\n return;\n }\n\n // Note: Actual file watching would require chokidar or similar\n // This is a placeholder for the integration point\n this.logger.info('File watching started', { \n plugin: pluginName,\n patterns: config.watchPatterns \n });\n }\n\n /**\n * Stop watching for changes\n */\n stopWatching(pluginName: string): void {\n const handle = this.watchHandles.get(pluginName);\n if (handle) {\n // Stop watching (would call chokidar close())\n this.watchHandles.delete(pluginName);\n this.logger.info('File watching stopped', { plugin: pluginName });\n }\n\n // Clear any pending reload timers\n const timer = this.reloadTimers.get(pluginName);\n if (timer) {\n clearTimeout(timer);\n this.reloadTimers.delete(pluginName);\n }\n }\n\n /**\n * Trigger hot reload for a plugin\n */\n async reloadPlugin(\n pluginName: string,\n plugin: Plugin,\n version: string,\n getPluginState: () => Record<string, any>,\n restorePluginState: (state: Record<string, any>) => void\n ): Promise<boolean> {\n const config = this.reloadConfigs.get(pluginName);\n if (!config) {\n this.logger.warn('Cannot reload - plugin not registered', { plugin: pluginName });\n return false;\n }\n\n this.logger.info('Starting hot reload', { plugin: pluginName });\n\n try {\n // Call before reload hooks\n if (config.beforeReload) {\n this.logger.debug('Executing before reload hooks', { \n plugin: pluginName,\n hooks: config.beforeReload \n });\n // Hook execution would be done through kernel's hook system\n }\n\n // Save state if configured\n let snapshotId: string | undefined;\n if (config.preserveState && config.stateStrategy !== 'none') {\n const state = getPluginState();\n snapshotId = await this.stateManager.saveState(\n pluginName,\n version,\n state,\n config\n );\n this.logger.debug('Plugin state saved', { plugin: pluginName, snapshotId });\n }\n\n // Gracefully shutdown the plugin\n if (plugin.destroy) {\n this.logger.debug('Destroying plugin', { plugin: pluginName });\n \n const shutdownPromise = plugin.destroy();\n const timeoutPromise = new Promise((_, reject) => {\n setTimeout(() => reject(new Error('Shutdown timeout')), config.shutdownTimeout);\n });\n\n await Promise.race([shutdownPromise, timeoutPromise]);\n this.logger.debug('Plugin destroyed successfully', { plugin: pluginName });\n }\n\n // At this point, the kernel would reload the plugin module\n // This would be handled by the plugin loader\n this.logger.debug('Plugin module would be reloaded here', { plugin: pluginName });\n\n // Restore state if we saved it\n if (snapshotId && config.preserveState) {\n const restoredState = await this.stateManager.restoreState(pluginName, snapshotId);\n if (restoredState) {\n restorePluginState(restoredState);\n this.logger.debug('Plugin state restored', { plugin: pluginName });\n }\n }\n\n // Call after reload hooks\n if (config.afterReload) {\n this.logger.debug('Executing after reload hooks', { \n plugin: pluginName,\n hooks: config.afterReload \n });\n // Hook execution would be done through kernel's hook system\n }\n\n this.logger.info('Hot reload completed successfully', { plugin: pluginName });\n return true;\n } catch (error) {\n this.logger.error('Hot reload failed', { \n plugin: pluginName, \n error \n });\n return false;\n }\n }\n\n /**\n * Schedule a reload with debouncing\n */\n scheduleReload(\n pluginName: string,\n reloadFn: () => Promise<void>\n ): void {\n const config = this.reloadConfigs.get(pluginName);\n if (!config) {\n return;\n }\n\n // Clear existing timer\n const existingTimer = this.reloadTimers.get(pluginName);\n if (existingTimer) {\n clearTimeout(existingTimer);\n }\n\n // Schedule new reload with debounce\n const timer = setTimeout(() => {\n this.logger.debug('Debounce period elapsed, executing reload', { \n plugin: pluginName \n });\n reloadFn().catch(error => {\n this.logger.error('Scheduled reload failed', { \n plugin: pluginName, \n error \n });\n });\n this.reloadTimers.delete(pluginName);\n }, config.debounceDelay);\n\n this.reloadTimers.set(pluginName, timer);\n this.logger.debug('Reload scheduled with debounce', { \n plugin: pluginName,\n delay: config.debounceDelay \n });\n }\n\n /**\n * Get state manager for direct access\n */\n getStateManager(): PluginStateManager {\n return this.stateManager;\n }\n\n /**\n * Shutdown hot reload manager\n */\n shutdown(): void {\n // Stop all watching\n for (const pluginName of this.watchHandles.keys()) {\n this.stopWatching(pluginName);\n }\n\n // Clear all timers\n for (const timer of this.reloadTimers.values()) {\n clearTimeout(timer);\n }\n\n this.reloadConfigs.clear();\n this.watchHandles.clear();\n this.reloadTimers.clear();\n this.stateManager.shutdown();\n \n this.logger.info('Hot reload manager shutdown complete');\n }\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport type { \n SemanticVersion,\n VersionConstraint,\n CompatibilityLevel,\n DependencyConflict\n} from '@objectstack/spec/kernel';\nimport type { ObjectLogger } from './logger.js';\n\n/**\n * Semantic Version Parser and Comparator\n * \n * Implements semantic versioning comparison and constraint matching\n */\nexport class SemanticVersionManager {\n /**\n * Parse a version string into semantic version components\n */\n static parse(versionStr: string): SemanticVersion {\n // Remove 'v' prefix if present\n const cleanVersion = versionStr.replace(/^v/, '');\n \n // Match semver pattern: major.minor.patch[-prerelease][+build]\n const match = cleanVersion.match(\n /^(\\d+)\\.(\\d+)\\.(\\d+)(?:-([a-zA-Z0-9.-]+))?(?:\\+([a-zA-Z0-9.-]+))?$/\n );\n\n if (!match) {\n throw new Error(`Invalid semantic version: ${versionStr}`);\n }\n\n return {\n major: parseInt(match[1], 10),\n minor: parseInt(match[2], 10),\n patch: parseInt(match[3], 10),\n preRelease: match[4],\n build: match[5],\n };\n }\n\n /**\n * Convert semantic version back to string\n */\n static toString(version: SemanticVersion): string {\n let str = `${version.major}.${version.minor}.${version.patch}`;\n if (version.preRelease) {\n str += `-${version.preRelease}`;\n }\n if (version.build) {\n str += `+${version.build}`;\n }\n return str;\n }\n\n /**\n * Compare two semantic versions\n * Returns: -1 if a < b, 0 if a === b, 1 if a > b\n */\n static compare(a: SemanticVersion, b: SemanticVersion): number {\n // Compare major, minor, patch\n if (a.major !== b.major) return a.major - b.major;\n if (a.minor !== b.minor) return a.minor - b.minor;\n if (a.patch !== b.patch) return a.patch - b.patch;\n\n // Pre-release versions have lower precedence\n if (a.preRelease && !b.preRelease) return -1;\n if (!a.preRelease && b.preRelease) return 1;\n \n // Compare pre-release versions\n if (a.preRelease && b.preRelease) {\n return a.preRelease.localeCompare(b.preRelease);\n }\n\n return 0;\n }\n\n /**\n * Check if version satisfies constraint\n */\n static satisfies(version: SemanticVersion, constraint: VersionConstraint): boolean {\n const constraintStr = constraint as string;\n\n // Any version\n if (constraintStr === '*' || constraintStr === 'latest') {\n return true;\n }\n\n // Exact version\n if (/^[\\d.]+$/.test(constraintStr)) {\n const exact = this.parse(constraintStr);\n return this.compare(version, exact) === 0;\n }\n\n // Caret range (^): Compatible with version\n if (constraintStr.startsWith('^')) {\n const base = this.parse(constraintStr.slice(1));\n return (\n version.major === base.major &&\n this.compare(version, base) >= 0\n );\n }\n\n // Tilde range (~): Approximately equivalent\n if (constraintStr.startsWith('~')) {\n const base = this.parse(constraintStr.slice(1));\n return (\n version.major === base.major &&\n version.minor === base.minor &&\n this.compare(version, base) >= 0\n );\n }\n\n // Greater than or equal\n if (constraintStr.startsWith('>=')) {\n const base = this.parse(constraintStr.slice(2));\n return this.compare(version, base) >= 0;\n }\n\n // Greater than\n if (constraintStr.startsWith('>')) {\n const base = this.parse(constraintStr.slice(1));\n return this.compare(version, base) > 0;\n }\n\n // Less than or equal\n if (constraintStr.startsWith('<=')) {\n const base = this.parse(constraintStr.slice(2));\n return this.compare(version, base) <= 0;\n }\n\n // Less than\n if (constraintStr.startsWith('<')) {\n const base = this.parse(constraintStr.slice(1));\n return this.compare(version, base) < 0;\n }\n\n // Range (1.2.3 - 2.3.4)\n const rangeMatch = constraintStr.match(/^([\\d.]+)\\s*-\\s*([\\d.]+)$/);\n if (rangeMatch) {\n const min = this.parse(rangeMatch[1]);\n const max = this.parse(rangeMatch[2]);\n return this.compare(version, min) >= 0 && this.compare(version, max) <= 0;\n }\n\n return false;\n }\n\n /**\n * Determine compatibility level between two versions\n */\n static getCompatibilityLevel(from: SemanticVersion, to: SemanticVersion): CompatibilityLevel {\n const cmp = this.compare(from, to);\n\n // Same version\n if (cmp === 0) {\n return 'fully-compatible';\n }\n\n // Major version changed - breaking changes\n if (from.major !== to.major) {\n return 'breaking-changes';\n }\n\n // Minor version increased - backward compatible\n if (from.minor < to.minor) {\n return 'backward-compatible';\n }\n\n // Patch version increased - fully compatible\n if (from.patch < to.patch) {\n return 'fully-compatible';\n }\n\n // Downgrade - incompatible\n return 'incompatible';\n }\n}\n\n/**\n * Plugin Dependency Resolver\n * \n * Resolves plugin dependencies using topological sorting and conflict detection\n */\nexport class DependencyResolver {\n private logger: ObjectLogger;\n\n constructor(logger: ObjectLogger) {\n this.logger = logger.child({ component: 'DependencyResolver' });\n }\n\n /**\n * Resolve dependencies using topological sort\n */\n resolve(\n plugins: Map<string, { version?: string; dependencies?: string[] }>\n ): string[] {\n const graph = new Map<string, string[]>();\n const inDegree = new Map<string, number>();\n\n // Build dependency graph\n for (const [pluginName, pluginInfo] of plugins) {\n if (!graph.has(pluginName)) {\n graph.set(pluginName, []);\n inDegree.set(pluginName, 0);\n }\n\n const deps = pluginInfo.dependencies || [];\n for (const dep of deps) {\n // Check if dependency exists\n if (!plugins.has(dep)) {\n throw new Error(`Missing dependency: ${pluginName} requires ${dep}`);\n }\n\n // Add edge\n if (!graph.has(dep)) {\n graph.set(dep, []);\n inDegree.set(dep, 0);\n }\n graph.get(dep)!.push(pluginName);\n inDegree.set(pluginName, (inDegree.get(pluginName) || 0) + 1);\n }\n }\n\n // Topological sort using Kahn's algorithm\n const queue: string[] = [];\n const result: string[] = [];\n\n // Add all nodes with no incoming edges\n for (const [node, degree] of inDegree) {\n if (degree === 0) {\n queue.push(node);\n }\n }\n\n while (queue.length > 0) {\n const node = queue.shift()!;\n result.push(node);\n\n // Reduce in-degree for dependent nodes\n const dependents = graph.get(node) || [];\n for (const dependent of dependents) {\n const newDegree = (inDegree.get(dependent) || 0) - 1;\n inDegree.set(dependent, newDegree);\n \n if (newDegree === 0) {\n queue.push(dependent);\n }\n }\n }\n\n // Check for circular dependencies\n if (result.length !== plugins.size) {\n const remaining = Array.from(plugins.keys()).filter(p => !result.includes(p));\n this.logger.error('Circular dependency detected', { remaining });\n throw new Error(`Circular dependency detected among: ${remaining.join(', ')}`);\n }\n\n this.logger.debug('Dependencies resolved', { order: result });\n return result;\n }\n\n /**\n * Detect dependency conflicts\n */\n detectConflicts(\n plugins: Map<string, { version: string; dependencies?: Record<string, VersionConstraint> }>\n ): DependencyConflict[] {\n const conflicts: DependencyConflict[] = [];\n const versionRequirements = new Map<string, Map<string, VersionConstraint>>();\n\n // Collect all version requirements\n for (const [pluginName, pluginInfo] of plugins) {\n if (!pluginInfo.dependencies) continue;\n\n for (const [depName, constraint] of Object.entries(pluginInfo.dependencies)) {\n if (!versionRequirements.has(depName)) {\n versionRequirements.set(depName, new Map());\n }\n versionRequirements.get(depName)!.set(pluginName, constraint);\n }\n }\n\n // Check for version mismatches\n for (const [depName, requirements] of versionRequirements) {\n const depInfo = plugins.get(depName);\n if (!depInfo) continue;\n\n const depVersion = SemanticVersionManager.parse(depInfo.version);\n const unsatisfied: Array<{ pluginId: string; version: string }> = [];\n\n for (const [requiringPlugin, constraint] of requirements) {\n if (!SemanticVersionManager.satisfies(depVersion, constraint)) {\n unsatisfied.push({\n pluginId: requiringPlugin,\n version: constraint as string,\n });\n }\n }\n\n if (unsatisfied.length > 0) {\n conflicts.push({\n type: 'version-mismatch',\n severity: 'error',\n description: `Version mismatch for ${depName}: detected ${unsatisfied.length} unsatisfied requirements`,\n plugins: [\n { pluginId: depName, version: depInfo.version },\n ...unsatisfied,\n ],\n resolutions: [{\n strategy: 'upgrade',\n description: `Upgrade ${depName} to satisfy all constraints`,\n targetPlugins: [depName],\n automatic: false,\n } as any],\n });\n }\n }\n\n // Check for circular dependencies (will be caught by resolve())\n try {\n this.resolve(new Map(\n Array.from(plugins.entries()).map(([name, info]) => [\n name,\n { version: info.version, dependencies: info.dependencies ? Object.keys(info.dependencies) : [] }\n ])\n ));\n } catch (error) {\n if (error instanceof Error && error.message.includes('Circular dependency')) {\n conflicts.push({\n type: 'circular-dependency',\n severity: 'critical',\n description: error.message,\n plugins: [], // Would need to extract from error\n resolutions: [{\n strategy: 'manual',\n description: 'Remove circular dependency by restructuring plugins',\n automatic: false,\n } as any],\n });\n }\n }\n\n return conflicts;\n }\n\n /**\n * Find best version that satisfies all constraints\n */\n findBestVersion(\n availableVersions: string[],\n constraints: VersionConstraint[]\n ): string | undefined {\n // Parse and sort versions (highest first)\n const versions = availableVersions\n .map(v => ({ str: v, parsed: SemanticVersionManager.parse(v) }))\n .sort((a, b) => -SemanticVersionManager.compare(a.parsed, b.parsed));\n\n // Find highest version that satisfies all constraints\n for (const version of versions) {\n const satisfiesAll = constraints.every(constraint =>\n SemanticVersionManager.satisfies(version.parsed, constraint)\n );\n\n if (satisfiesAll) {\n return version.str;\n }\n }\n\n return undefined;\n }\n\n /**\n * Check if dependencies form a valid DAG (no cycles)\n */\n isAcyclic(dependencies: Map<string, string[]>): boolean {\n try {\n const plugins = new Map(\n Array.from(dependencies.entries()).map(([name, deps]) => [\n name,\n { dependencies: deps }\n ])\n );\n this.resolve(plugins);\n return true;\n } catch {\n return false;\n }\n }\n}\n"],"mappings":"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","names":["ServiceLifecycle","service"]}