@sonicjs-cms/core 3.0.0-beta.7 → 3.0.0-beta.9

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.
Files changed (73) hide show
  1. package/dist/{filter-bar.template-DlVYMk-T.d.cts → admin-layout-catalyst.template-DrwDUfsE.d.cts} +25 -1
  2. package/dist/{filter-bar.template-DlVYMk-T.d.ts → admin-layout-catalyst.template-DrwDUfsE.d.ts} +25 -1
  3. package/dist/{chunk-GO2NICMM.cjs → chunk-2FONGKMG.cjs} +237 -237
  4. package/dist/{chunk-GO2NICMM.cjs.map → chunk-2FONGKMG.cjs.map} +1 -1
  5. package/dist/{chunk-GVHST4D7.js → chunk-3WSZNGIK.js} +50 -4
  6. package/dist/chunk-3WSZNGIK.js.map +1 -0
  7. package/dist/{chunk-BDDABDAB.cjs → chunk-4BTBSXMR.cjs} +2 -239
  8. package/dist/chunk-4BTBSXMR.cjs.map +1 -0
  9. package/dist/{chunk-7RY3YKI7.cjs → chunk-7AMFLNK6.cjs} +3 -3
  10. package/dist/{chunk-7RY3YKI7.cjs.map → chunk-7AMFLNK6.cjs.map} +1 -1
  11. package/dist/{chunk-WACUJVXY.cjs → chunk-C5RJWUZX.cjs} +57 -11
  12. package/dist/chunk-C5RJWUZX.cjs.map +1 -0
  13. package/dist/{chunk-2JOMHEKO.js → chunk-E2LLKPFQ.js} +3 -3
  14. package/dist/{chunk-2JOMHEKO.js.map → chunk-E2LLKPFQ.js.map} +1 -1
  15. package/dist/{chunk-5QVYEAVV.cjs → chunk-ITXAUOBC.cjs} +10 -10
  16. package/dist/{chunk-5QVYEAVV.cjs.map → chunk-ITXAUOBC.cjs.map} +1 -1
  17. package/dist/{chunk-2RJDEVB3.cjs → chunk-J46JBAZX.cjs} +2 -2
  18. package/dist/{chunk-2RJDEVB3.cjs.map → chunk-J46JBAZX.cjs.map} +1 -1
  19. package/dist/{chunk-XCPIXYOP.js → chunk-NSE36XKR.js} +4 -4
  20. package/dist/{chunk-XCPIXYOP.js.map → chunk-NSE36XKR.js.map} +1 -1
  21. package/dist/{chunk-WJTMTIYR.js → chunk-PYVFXCSD.js} +255 -3
  22. package/dist/chunk-PYVFXCSD.js.map +1 -0
  23. package/dist/{chunk-OECDF2RF.cjs → chunk-R4ILO3W6.cjs} +258 -2
  24. package/dist/chunk-R4ILO3W6.cjs.map +1 -0
  25. package/dist/{chunk-ZEZ245PW.js → chunk-RQ6N3FTV.js} +3 -236
  26. package/dist/chunk-RQ6N3FTV.js.map +1 -0
  27. package/dist/{chunk-ISIRU7AK.cjs → chunk-RU5TA4J7.cjs} +4 -4
  28. package/dist/{chunk-ISIRU7AK.cjs.map → chunk-RU5TA4J7.cjs.map} +1 -1
  29. package/dist/{chunk-BYCBFBUG.js → chunk-SBVOWPJ5.js} +2 -2
  30. package/dist/{chunk-BYCBFBUG.js.map → chunk-SBVOWPJ5.js.map} +1 -1
  31. package/dist/{chunk-LH7RKNUW.js → chunk-VHYQ67LW.js} +10 -10
  32. package/dist/{chunk-LH7RKNUW.js.map → chunk-VHYQ67LW.js.map} +1 -1
  33. package/dist/{chunk-POGSN5WI.js → chunk-ZHPOJZRR.js} +3 -3
  34. package/dist/{chunk-POGSN5WI.js.map → chunk-ZHPOJZRR.js.map} +1 -1
  35. package/dist/index.cjs +264 -260
  36. package/dist/index.cjs.map +1 -1
  37. package/dist/index.d.cts +2 -1
  38. package/dist/index.d.ts +2 -1
  39. package/dist/index.js +17 -16
  40. package/dist/index.js.map +1 -1
  41. package/dist/middleware.cjs +33 -32
  42. package/dist/middleware.js +4 -3
  43. package/dist/migrations-6MRNHE2W.cjs +13 -0
  44. package/dist/{migrations-TBEFSZIV.cjs.map → migrations-6MRNHE2W.cjs.map} +1 -1
  45. package/dist/migrations-SBX554MG.js +4 -0
  46. package/dist/{migrations-IEWABLIP.js.map → migrations-SBX554MG.js.map} +1 -1
  47. package/dist/plugins.cjs +40 -40
  48. package/dist/plugins.js +3 -3
  49. package/dist/routes.cjs +28 -28
  50. package/dist/routes.js +8 -8
  51. package/dist/services.cjs +42 -42
  52. package/dist/services.d.cts +14 -1
  53. package/dist/services.d.ts +14 -1
  54. package/dist/services.js +3 -3
  55. package/dist/{telemetry-B9vIV4wh.d.cts → telemetry-Cku1ax74.d.cts} +1 -1
  56. package/dist/{telemetry-B9vIV4wh.d.ts → telemetry-Cku1ax74.d.ts} +1 -1
  57. package/dist/templates.d.cts +2 -24
  58. package/dist/templates.d.ts +2 -24
  59. package/dist/types.d.cts +1 -1
  60. package/dist/types.d.ts +1 -1
  61. package/dist/utils.cjs +8 -8
  62. package/dist/utils.d.cts +1 -1
  63. package/dist/utils.d.ts +1 -1
  64. package/dist/utils.js +2 -2
  65. package/package.json +1 -1
  66. package/dist/chunk-BDDABDAB.cjs.map +0 -1
  67. package/dist/chunk-GVHST4D7.js.map +0 -1
  68. package/dist/chunk-OECDF2RF.cjs.map +0 -1
  69. package/dist/chunk-WACUJVXY.cjs.map +0 -1
  70. package/dist/chunk-WJTMTIYR.js.map +0 -1
  71. package/dist/chunk-ZEZ245PW.js.map +0 -1
  72. package/dist/migrations-IEWABLIP.js +0 -4
  73. package/dist/migrations-TBEFSZIV.cjs +0 -13
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/services/logger.ts","../src/services/cache.ts","../src/services/settings.ts","../src/services/telemetry-service.ts","../src/services/route-metadata.ts"],"names":["drizzle","systemLogs","inArray","eq","like","gte","lte","and","count","asc","desc","logConfig","getCacheService","getTelemetryConfig","sanitizeErrorMessage","sanitizeRoute","generateInstallationId","generateProjectId","inspectRoutes"],"mappings":"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","file":"chunk-BDDABDAB.cjs","sourcesContent":["import type { D1Database } from '@cloudflare/workers-types'\nimport { systemLogs, logConfig, type NewSystemLog, type LogConfig } from '../db/schema'\nimport { drizzle } from 'drizzle-orm/d1'\nimport { eq, and, gte, lte, desc, asc, count, like, inArray } from 'drizzle-orm'\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'fatal'\nexport type LogCategory = 'auth' | 'api' | 'workflow' | 'plugin' | 'media' | 'system' | 'security' | 'error'\n\nexport interface LogEntry {\n level: LogLevel\n category: LogCategory\n message: string\n data?: any\n userId?: string\n sessionId?: string\n requestId?: string\n ipAddress?: string\n userAgent?: string\n method?: string\n url?: string\n statusCode?: number\n duration?: number\n stackTrace?: string\n tags?: string[]\n source?: string\n}\n\nexport interface LogFilter {\n level?: LogLevel[]\n category?: LogCategory[]\n userId?: string\n source?: string\n search?: string\n startDate?: Date\n endDate?: Date\n tags?: string[]\n limit?: number\n offset?: number\n sortBy?: 'created_at' | 'level' | 'category'\n sortOrder?: 'asc' | 'desc'\n}\n\nexport class Logger {\n private db: ReturnType<typeof drizzle>\n private enabled: boolean = true\n private configCache: Map<string, LogConfig> = new Map()\n private lastConfigRefresh: number = 0\n private configRefreshInterval: number = 60000 // 1 minute\n\n constructor(database: D1Database) {\n this.db = drizzle(database)\n }\n\n /**\n * Log a debug message\n */\n async debug(category: LogCategory, message: string, data?: any, context?: Partial<LogEntry>): Promise<void> {\n return this.log('debug', category, message, data, context)\n }\n\n /**\n * Log an info message\n */\n async info(category: LogCategory, message: string, data?: any, context?: Partial<LogEntry>): Promise<void> {\n return this.log('info', category, message, data, context)\n }\n\n /**\n * Log a warning message\n */\n async warn(category: LogCategory, message: string, data?: any, context?: Partial<LogEntry>): Promise<void> {\n return this.log('warn', category, message, data, context)\n }\n\n /**\n * Log an error message\n */\n async error(category: LogCategory, message: string, error?: Error | any, context?: Partial<LogEntry>): Promise<void> {\n const errorData = error instanceof Error ? {\n name: error.name,\n message: error.message,\n stack: error.stack\n } : error\n\n return this.log('error', category, message, errorData, {\n ...context,\n stackTrace: error instanceof Error ? error.stack : undefined\n })\n }\n\n /**\n * Log a fatal message\n */\n async fatal(category: LogCategory, message: string, error?: Error | any, context?: Partial<LogEntry>): Promise<void> {\n const errorData = error instanceof Error ? {\n name: error.name,\n message: error.message,\n stack: error.stack\n } : error\n\n return this.log('fatal', category, message, errorData, {\n ...context,\n stackTrace: error instanceof Error ? error.stack : undefined\n })\n }\n\n /**\n * Log an API request\n */\n async logRequest(\n method: string,\n url: string,\n statusCode: number,\n duration: number,\n context?: Partial<LogEntry>\n ): Promise<void> {\n const level: LogLevel = statusCode >= 500 ? 'error' : statusCode >= 400 ? 'warn' : 'info'\n \n return this.log(level, 'api', `${method} ${url} - ${statusCode}`, {\n method,\n url,\n statusCode,\n duration\n }, {\n ...context,\n method,\n url,\n statusCode,\n duration\n })\n }\n\n /**\n * Log an authentication event\n */\n async logAuth(action: string, userId?: string, success: boolean = true, context?: Partial<LogEntry>): Promise<void> {\n const level: LogLevel = success ? 'info' : 'warn'\n \n return this.log(level, 'auth', `Authentication ${action}: ${success ? 'success' : 'failed'}`, {\n action,\n success,\n userId\n }, {\n ...context,\n userId,\n tags: ['authentication', action]\n })\n }\n\n /**\n * Log a security event\n */\n async logSecurity(event: string, severity: 'low' | 'medium' | 'high' | 'critical', context?: Partial<LogEntry>): Promise<void> {\n const level: LogLevel = severity === 'critical' ? 'fatal' : severity === 'high' ? 'error' : 'warn'\n \n return this.log(level, 'security', `Security event: ${event}`, {\n event,\n severity\n }, {\n ...context,\n tags: ['security', severity]\n })\n }\n\n /**\n * Core logging method\n */\n private async log(\n level: LogLevel,\n category: LogCategory,\n message: string,\n data?: any,\n context?: Partial<LogEntry>\n ): Promise<void> {\n if (!this.enabled) return\n\n try {\n // Check if logging is enabled for this category and level\n const config = await this.getConfig(category)\n if (!config || !config.enabled || !this.shouldLog(level, config.level)) {\n return\n }\n\n const logEntry: NewSystemLog = {\n id: crypto.randomUUID(),\n level,\n category,\n message,\n data: data ? JSON.stringify(data) : null,\n userId: context?.userId || null,\n sessionId: context?.sessionId || null,\n requestId: context?.requestId || null,\n ipAddress: context?.ipAddress || null,\n userAgent: context?.userAgent || null,\n method: context?.method || null,\n url: context?.url || null,\n statusCode: context?.statusCode || null,\n duration: context?.duration || null,\n stackTrace: context?.stackTrace || null,\n tags: context?.tags ? JSON.stringify(context.tags) : null,\n source: context?.source || null,\n createdAt: new Date()\n }\n\n await this.db.insert(systemLogs).values(logEntry)\n\n // Check if we need to clean up old logs\n if (config.maxSize) {\n await this.cleanupCategory(category, config.maxSize)\n }\n\n } catch (error) {\n // Don't log errors in the logger to avoid infinite loops\n console.error('Logger error:', error)\n }\n }\n\n /**\n * Get logs with filtering and pagination\n */\n async getLogs(filter: LogFilter = {}): Promise<{ logs: any[], total: number }> {\n try {\n const conditions = []\n \n if (filter.level && filter.level.length > 0) {\n conditions.push(inArray(systemLogs.level, filter.level))\n }\n \n if (filter.category && filter.category.length > 0) {\n conditions.push(inArray(systemLogs.category, filter.category))\n }\n \n if (filter.userId) {\n conditions.push(eq(systemLogs.userId, filter.userId))\n }\n \n if (filter.source) {\n conditions.push(eq(systemLogs.source, filter.source))\n }\n \n if (filter.search) {\n conditions.push(\n like(systemLogs.message, `%${filter.search}%`)\n )\n }\n \n if (filter.startDate) {\n conditions.push(gte(systemLogs.createdAt, filter.startDate))\n }\n \n if (filter.endDate) {\n conditions.push(lte(systemLogs.createdAt, filter.endDate))\n }\n\n const whereClause = conditions.length > 0 ? and(...conditions) : undefined\n\n // Get total count\n const totalResult = await this.db\n .select({ count: count() })\n .from(systemLogs)\n .where(whereClause)\n\n const total = totalResult[0]?.count || 0\n\n // Get logs with pagination and sorting\n const sortColumn = filter.sortBy === 'level' ? systemLogs.level :\n filter.sortBy === 'category' ? systemLogs.category :\n systemLogs.createdAt\n\n const sortFn = filter.sortOrder === 'asc' ? asc : desc\n\n const logs = await this.db\n .select()\n .from(systemLogs)\n .where(whereClause)\n .orderBy(sortFn(sortColumn))\n .limit(filter.limit || 50)\n .offset(filter.offset || 0)\n\n return { logs, total }\n } catch (error) {\n console.error('Error getting logs:', error)\n return { logs: [], total: 0 }\n }\n }\n\n /**\n * Get log configuration for a category\n */\n private async getConfig(category: LogCategory): Promise<LogConfig | null> {\n try {\n // Check cache first\n const now = Date.now()\n if (this.configCache.has(category) && (now - this.lastConfigRefresh) < this.configRefreshInterval) {\n return this.configCache.get(category) || null\n }\n\n // Refresh config from database\n const configs = await this.db\n .select()\n .from(logConfig)\n .where(eq(logConfig.category, category))\n\n const config = configs[0] || null\n \n if (config) {\n this.configCache.set(category, config)\n this.lastConfigRefresh = now\n }\n\n return config\n } catch (error) {\n console.error('Error getting log config:', error)\n return null\n }\n }\n\n /**\n * Update log configuration\n */\n async updateConfig(category: LogCategory, updates: Partial<LogConfig>): Promise<void> {\n try {\n await this.db\n .update(logConfig)\n .set({\n ...updates,\n updatedAt: new Date()\n })\n .where(eq(logConfig.category, category))\n\n // Clear cache for this category\n this.configCache.delete(category)\n } catch (error) {\n console.error('Error updating log config:', error)\n }\n }\n\n /**\n * Get all log configurations\n */\n async getAllConfigs(): Promise<LogConfig[]> {\n try {\n return await this.db.select().from(logConfig)\n } catch (error) {\n console.error('Error getting log configs:', error)\n return []\n }\n }\n\n /**\n * Clean up old logs for a category\n */\n private async cleanupCategory(category: LogCategory, maxSize: number): Promise<void> {\n try {\n // Count current logs for this category\n const countResult = await this.db\n .select({ count: count() })\n .from(systemLogs)\n .where(eq(systemLogs.category, category))\n\n const currentCount = countResult[0]?.count || 0\n\n if (currentCount > maxSize) {\n // Get the cutoff date (keep newest maxSize logs)\n const cutoffLogs = await this.db\n .select({ createdAt: systemLogs.createdAt })\n .from(systemLogs)\n .where(eq(systemLogs.category, category))\n .orderBy(desc(systemLogs.createdAt))\n .limit(1)\n .offset(maxSize - 1)\n\n if (cutoffLogs[0]) {\n // Delete older logs\n await this.db\n .delete(systemLogs)\n .where(\n and(\n eq(systemLogs.category, category),\n lte(systemLogs.createdAt, cutoffLogs[0].createdAt)\n )\n )\n }\n }\n } catch (error) {\n console.error('Error cleaning up logs:', error)\n }\n }\n\n /**\n * Clean up logs based on retention policy\n */\n async cleanupByRetention(): Promise<void> {\n try {\n const configs = await this.getAllConfigs()\n \n for (const config of configs) {\n if (config.retention > 0) {\n const cutoffDate = new Date()\n cutoffDate.setDate(cutoffDate.getDate() - config.retention)\n\n await this.db\n .delete(systemLogs)\n .where(\n and(\n eq(systemLogs.category, config.category),\n lte(systemLogs.createdAt, cutoffDate)\n )\n )\n }\n }\n } catch (error) {\n console.error('Error cleaning up logs by retention:', error)\n }\n }\n\n /**\n * Check if a log level should be recorded based on configuration\n */\n private shouldLog(level: LogLevel, configLevel: string): boolean {\n const levels = ['debug', 'info', 'warn', 'error', 'fatal']\n const levelIndex = levels.indexOf(level)\n const configLevelIndex = levels.indexOf(configLevel)\n \n return levelIndex >= configLevelIndex\n }\n\n /**\n * Enable or disable logging\n */\n setEnabled(enabled: boolean): void {\n this.enabled = enabled\n }\n\n /**\n * Check if logging is enabled\n */\n isEnabled(): boolean {\n return this.enabled\n }\n}\n\n// Singleton logger instance\nlet loggerInstance: Logger | null = null\n\n/**\n * Get the logger instance\n */\nexport function getLogger(database?: D1Database): Logger {\n if (!loggerInstance && database) {\n loggerInstance = new Logger(database)\n }\n \n if (!loggerInstance) {\n throw new Error('Logger not initialized. Call getLogger with a database instance first.')\n }\n \n return loggerInstance\n}\n\n/**\n * Initialize the logger with a database\n */\nexport function initLogger(database: D1Database): Logger {\n loggerInstance = new Logger(database)\n return loggerInstance\n}","/**\n * Cache Service Adapter\n *\n * Thin facade over the cache plugin's `CacheService` so route code can keep its\n * legacy `{ ttl, keyPrefix }` contract while writes land in the plugin's\n * singleton — that's the same registry the admin dashboard at /admin/cache reads\n * via `getAllCacheStats()`. Without this adapter the two caches would be split:\n * routes would write to one, the dashboard would read from another, and the UI\n * would always show zero entries.\n */\n\nimport {\n getCacheService as getPluginCacheService,\n type CacheService as PluginCacheService,\n} from '../plugins/cache/services/cache'\nimport type { CacheConfig as PluginCacheConfig } from '../plugins/cache/services/cache-config'\n\nexport interface CacheConfig {\n ttl: number // Time to live in seconds\n keyPrefix: string\n}\n\nfunction toPluginConfig(config: CacheConfig): PluginCacheConfig {\n return {\n ttl: config.ttl,\n namespace: config.keyPrefix,\n // KV survives isolate evictions — required for the dashboard to show non-zero\n // counts across requests in production. Falls back to memory-only when the\n // CACHE_KV binding is missing (cache plugin handles the null case).\n kvEnabled: true,\n memoryEnabled: true,\n invalidateOn: [],\n version: 'v1',\n }\n}\n\nexport class CacheService {\n private config: CacheConfig\n private inner: PluginCacheService\n // Tracks expiry times so getWithSource can distinguish 'none' vs 'expired'.\n // The plugin returns source:'miss' for both cases; we differentiate here.\n private keyExpiry = new Map<string, number>()\n\n constructor(config: CacheConfig) {\n this.config = config\n this.inner = getPluginCacheService(toPluginConfig(config))\n }\n\n generateKey(type: string, identifier?: string): string {\n const parts = [this.config.keyPrefix, type]\n if (identifier !== undefined && identifier !== '') parts.push(identifier)\n return parts.join(':')\n }\n\n async get<T>(key: string): Promise<T | null> {\n return this.inner.get<T>(key)\n }\n\n async getWithSource<T>(key: string): Promise<{\n hit: boolean\n data: T | null\n source: string\n ttl?: number\n }> {\n const result = await this.inner.getWithSource<T>(key)\n if (result.hit) {\n const out: { hit: boolean; data: T | null; source: string; ttl?: number } = {\n hit: true,\n data: result.data,\n source: result.source,\n }\n if (result.ttl !== undefined) out.ttl = result.ttl\n return out\n }\n // Plugin returns source:'miss' for both \"never set\" and \"expired\". Distinguish\n // by checking if we ever recorded an expiry for this key.\n const expiry = this.keyExpiry.get(key)\n if (expiry !== undefined) {\n this.keyExpiry.delete(key)\n return { hit: false, data: null, source: 'expired' }\n }\n return { hit: false, data: null, source: 'none' }\n }\n\n async set(key: string, value: any, ttl?: number): Promise<void> {\n const effectiveTtl = ttl ?? this.config.ttl\n this.keyExpiry.set(key, Date.now() + effectiveTtl * 1000)\n await this.inner.set(key, value, ttl !== undefined ? { ttl } : undefined)\n }\n\n async delete(key: string): Promise<void> {\n this.keyExpiry.delete(key)\n await this.inner.delete(key)\n }\n\n async invalidate(pattern: string): Promise<void> {\n // Clear expiry tracking for invalidated keys\n if (pattern.includes('*') || pattern.includes('?')) {\n const regex = new RegExp('^' + pattern.replace(/\\*/g, '.*').replace(/\\?/g, '.') + '$')\n for (const k of this.keyExpiry.keys()) {\n if (regex.test(k)) this.keyExpiry.delete(k)\n }\n } else {\n this.keyExpiry.delete(pattern)\n }\n await this.inner.invalidate(pattern)\n }\n\n async clear(): Promise<void> {\n this.keyExpiry.clear()\n await this.inner.clear()\n }\n\n async getOrSet<T>(key: string, callback: () => Promise<T>, ttl?: number): Promise<T> {\n const cached = await this.get<T>(key)\n if (cached !== null) return cached\n const value = await callback()\n await this.set(key, value, ttl)\n return value\n }\n}\n\n/**\n * Default cache configurations for different data types.\n */\nexport const CACHE_CONFIGS = {\n api: {\n ttl: 300, // 5 minutes\n keyPrefix: 'api',\n },\n user: {\n ttl: 600, // 10 minutes\n keyPrefix: 'user',\n },\n content: {\n ttl: 300, // 5 minutes\n keyPrefix: 'content',\n },\n collection: {\n ttl: 600, // 10 minutes\n keyPrefix: 'collection',\n },\n}\n\n/**\n * Resolve a cache service for a config. Wraps the plugin's singleton so admin\n * dashboard stats and route-side writes share the same store.\n */\nexport function getCacheService(config: CacheConfig): CacheService {\n return new CacheService(config)\n}\n\n/** Clear every cached value across all plugin singletons. Test/admin use only. */\nexport async function clearAllCacheInstances(): Promise<void> {\n const { clearAllCaches } = await import('../plugins/cache/services/cache')\n await clearAllCaches()\n}\n","export interface GeneralSettings {\n siteName: string\n siteDescription: string\n adminEmail: string\n timezone: string\n language: string\n maintenanceMode: boolean\n}\n\nexport interface SecuritySettings {\n jwtExpiresIn: string\n jwtRefreshGraceSeconds: number\n}\n\nconst TYPE_ID = 'site_settings'\nconst TENANT = 'default'\n\nexport class SettingsService {\n constructor(private db: D1Database) {}\n\n /**\n * Get settings document for a category (general or security)\n */\n private async getSettingsDocument(category: string): Promise<any | null> {\n try {\n const row = await this.db.prepare(`\n SELECT data FROM documents\n WHERE type_id = ? AND slug = ? AND tenant_id = ? AND is_current_draft = 1 AND deleted_at IS NULL\n `).bind(TYPE_ID, category, TENANT).first()\n\n if (!row) {\n return null\n }\n\n return JSON.parse((row as any).data)\n } catch (error) {\n console.error(`Error getting settings document for ${category}:`, error)\n return null\n }\n }\n\n /**\n * Save settings document for a category (general or security)\n */\n private async saveSettingsDocument(category: string, data: Record<string, any>): Promise<boolean> {\n try {\n const now = Math.floor(Date.now() / 1000)\n const jsonData = JSON.stringify(data)\n\n // Ensure document_types row exists (FK constraint on documents.type_id)\n await this.db.prepare(`\n INSERT OR IGNORE INTO document_types (id, name, display_name, description, schema, source, is_system, is_active, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `).bind(\n TYPE_ID, TYPE_ID, 'Site Settings',\n 'Global site configuration settings',\n '{}', 'system', 1, 1, now, now\n ).run()\n\n // Check if document already exists\n const existing = await this.db.prepare(`\n SELECT id FROM documents\n WHERE type_id = ? AND slug = ? AND tenant_id = ? AND is_current_draft = 1 AND deleted_at IS NULL\n `).bind(TYPE_ID, category, TENANT).first() as any\n\n if (existing) {\n // Update existing document\n await this.db.prepare(`\n UPDATE documents\n SET data = ?, updated_at = ?\n WHERE id = ? AND is_current_draft = 1\n `).bind(jsonData, now, existing.id).run()\n } else {\n // Create new document\n const docId = crypto.randomUUID()\n const rootId = docId\n const title = category === 'general' ? 'General Settings' : 'Security Settings'\n\n await this.db.prepare(`\n INSERT INTO documents (\n id, root_id, type_id, version_number, is_current_draft, is_published, status,\n parent_root_id, slug, title, tenant_id, locale, translation_group_id,\n data, metadata, created_at, updated_at\n ) VALUES (\n ?, ?, ?, 1, 1, 1, 'published',\n '', ?, ?, ?, 'default', '',\n ?, '{}', ?, ?\n )\n `).bind(\n docId, rootId, TYPE_ID,\n category, title, TENANT,\n jsonData, now, now\n ).run()\n }\n\n return true\n } catch (error) {\n console.error(`Error saving settings document for ${category}:`, error)\n return false\n }\n }\n\n /**\n * Get general settings with defaults\n */\n async getGeneralSettings(userEmail?: string): Promise<GeneralSettings> {\n const settings = await this.getSettingsDocument('general')\n\n return {\n siteName: settings?.siteName || 'SonicJS AI',\n siteDescription: settings?.siteDescription || 'A modern headless CMS powered by AI',\n adminEmail: settings?.adminEmail || userEmail || 'admin@example.com',\n timezone: settings?.timezone || 'UTC',\n language: settings?.language || 'en',\n maintenanceMode: settings?.maintenanceMode || false\n }\n }\n\n /**\n * Save general settings\n */\n async saveGeneralSettings(settings: Partial<GeneralSettings>): Promise<boolean> {\n const existing = await this.getSettingsDocument('general')\n const merged = { ...existing, ...settings }\n return await this.saveSettingsDocument('general', merged)\n }\n\n /**\n * Get security settings with defaults\n */\n async getSecuritySettings(): Promise<SecuritySettings> {\n const settings = await this.getSettingsDocument('security')\n\n return {\n jwtExpiresIn: settings?.jwtExpiresIn || '30d',\n jwtRefreshGraceSeconds:\n typeof settings?.jwtRefreshGraceSeconds === 'number'\n ? settings.jwtRefreshGraceSeconds\n : 60 * 60 * 24 * 7\n }\n }\n\n /**\n * Save security settings\n */\n async saveSecuritySettings(settings: Partial<SecuritySettings>): Promise<boolean> {\n const existing = await this.getSettingsDocument('security')\n const merged = { ...existing, ...settings }\n return await this.saveSettingsDocument('security', merged)\n }\n}\n","/**\n * Telemetry Service\n *\n * Privacy-first telemetry service using custom SonicJS stats endpoint\n * - No PII collection\n * - Opt-out by default\n * - Silent failures (never blocks app)\n */\n\nimport type { TelemetryEvent, TelemetryProperties, TelemetryConfig, TelemetryIdentity } from '../types/telemetry'\nimport { getTelemetryConfig } from '../utils/telemetry-config'\nimport { generateInstallationId, generateProjectId, sanitizeErrorMessage, sanitizeRoute } from '../utils/telemetry-id'\n\n/**\n * TelemetryService class\n *\n * Handles all telemetry tracking in a privacy-conscious way\n */\nexport class TelemetryService {\n private config: TelemetryConfig\n private identity: TelemetryIdentity | null = null\n private enabled: boolean = true\n private eventQueue: Array<{ event: TelemetryEvent; properties?: TelemetryProperties }> = []\n private isInitialized: boolean = false\n\n constructor(config?: Partial<TelemetryConfig>) {\n this.config = {\n ...getTelemetryConfig(),\n ...config\n }\n this.enabled = this.config.enabled\n }\n\n /**\n * Initialize the telemetry service\n */\n async initialize(identity: TelemetryIdentity): Promise<void> {\n if (!this.enabled) {\n if (this.config.debug) {\n console.log('[Telemetry] Disabled via configuration')\n }\n return\n }\n\n try {\n this.identity = identity\n\n if (this.config.debug) {\n console.log('[Telemetry] Initialized with installation ID:', identity.installationId)\n }\n\n this.isInitialized = true\n\n // Flush any queued events\n await this.flushQueue()\n\n } catch (error) {\n // Silent fail - telemetry should never break the app\n if (this.config.debug) {\n console.error('[Telemetry] Initialization failed:', error)\n }\n this.enabled = false\n }\n }\n\n /**\n * Track a telemetry event\n */\n async track(event: TelemetryEvent, properties?: TelemetryProperties): Promise<void> {\n if (!this.enabled) return\n\n try {\n // Sanitize properties\n const sanitizedProps = this.sanitizeProperties(properties)\n\n // Add standard properties\n const enrichedProps = {\n ...sanitizedProps,\n timestamp: new Date().toISOString(),\n version: this.getVersion()\n }\n\n // If not initialized, queue the event\n if (!this.isInitialized) {\n this.eventQueue.push({ event, properties: enrichedProps })\n if (this.config.debug) {\n console.log('[Telemetry] Queued event:', event, enrichedProps)\n }\n return\n }\n\n // Send to custom SonicJS stats endpoint\n if (this.identity && this.config.host) {\n const payload = {\n data: {\n installation_id: this.identity.installationId,\n event_type: event,\n properties: enrichedProps,\n timestamp: enrichedProps.timestamp\n }\n }\n\n // Fire and forget - don't block on response\n fetch(`${this.config.host}/v1/events`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload)\n }).catch(() => {}) // Silent fail\n\n if (this.config.debug) {\n console.log('[Telemetry] Tracked event:', event, enrichedProps)\n }\n } else if (this.config.debug) {\n console.log('[Telemetry] Event (no endpoint):', event, enrichedProps)\n }\n\n } catch (error) {\n // Silent fail\n if (this.config.debug) {\n console.error('[Telemetry] Failed to track event:', error)\n }\n }\n }\n\n /**\n * Track installation started\n */\n async trackInstallationStarted(properties?: TelemetryProperties): Promise<void> {\n await this.track('installation_started', properties)\n }\n\n /**\n * Track installation completed\n */\n async trackInstallationCompleted(properties?: TelemetryProperties): Promise<void> {\n await this.track('installation_completed', properties)\n }\n\n /**\n * Track installation failed\n */\n async trackInstallationFailed(error: Error | string, properties?: TelemetryProperties): Promise<void> {\n await this.track('installation_failed', {\n ...properties,\n errorType: sanitizeErrorMessage(error)\n })\n }\n\n /**\n * Track dev server started\n */\n async trackDevServerStarted(properties?: TelemetryProperties): Promise<void> {\n await this.track('dev_server_started', properties)\n }\n\n /**\n * Track page view in admin UI\n */\n async trackPageView(route: string, properties?: TelemetryProperties): Promise<void> {\n await this.track('page_viewed', {\n ...properties,\n route: sanitizeRoute(route)\n })\n }\n\n /**\n * Track error (sanitized)\n */\n async trackError(error: Error | string, properties?: TelemetryProperties): Promise<void> {\n await this.track('error_occurred', {\n ...properties,\n errorType: sanitizeErrorMessage(error)\n })\n }\n\n /**\n * Track plugin activation\n */\n async trackPluginActivated(properties?: TelemetryProperties): Promise<void> {\n await this.track('plugin_activated', properties)\n }\n\n /**\n * Track migration run\n */\n async trackMigrationRun(properties?: TelemetryProperties): Promise<void> {\n await this.track('migration_run', properties)\n }\n\n /**\n * Flush queued events\n */\n private async flushQueue(): Promise<void> {\n if (this.eventQueue.length === 0) return\n\n const queue = [...this.eventQueue]\n this.eventQueue = []\n\n for (const { event, properties } of queue) {\n await this.track(event, properties)\n }\n }\n\n /**\n * Sanitize properties to ensure no PII\n */\n private sanitizeProperties(properties?: TelemetryProperties): TelemetryProperties {\n if (!properties) return {}\n\n const sanitized: TelemetryProperties = {}\n\n for (const [key, value] of Object.entries(properties)) {\n // Skip undefined values\n if (value === undefined) continue\n\n // Sanitize routes\n if (key === 'route' && typeof value === 'string') {\n sanitized[key] = sanitizeRoute(value)\n continue\n }\n\n // Sanitize error messages\n if (key.toLowerCase().includes('error') && typeof value === 'string') {\n sanitized[key] = sanitizeErrorMessage(value)\n continue\n }\n\n // Only allow specific types\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n sanitized[key] = value\n }\n }\n\n return sanitized\n }\n\n /**\n * Get SonicJS version\n */\n private getVersion(): string {\n try {\n // Safe environment access for Cloudflare Workers compatibility\n if (typeof process !== 'undefined' && process.env) {\n return process.env.SONICJS_VERSION || '2.0.0'\n }\n return '2.0.0'\n } catch {\n return 'unknown'\n }\n }\n\n /**\n * Shutdown the telemetry service (no-op for fetch-based telemetry)\n */\n async shutdown(): Promise<void> {\n // No-op - fetch requests are fire and forget\n }\n\n /**\n * Enable telemetry\n */\n enable(): void {\n this.enabled = true\n }\n\n /**\n * Disable telemetry\n */\n disable(): void {\n this.enabled = false\n }\n\n /**\n * Check if telemetry is enabled\n */\n isEnabled(): boolean {\n return this.enabled\n }\n}\n\n// Singleton instance\nlet telemetryInstance: TelemetryService | null = null\n\n/**\n * Get the telemetry service instance\n */\nexport function getTelemetryService(config?: Partial<TelemetryConfig>): TelemetryService {\n if (!telemetryInstance) {\n telemetryInstance = new TelemetryService(config)\n }\n return telemetryInstance\n}\n\n/**\n * Initialize telemetry service\n */\nexport async function initTelemetry(identity: TelemetryIdentity, config?: Partial<TelemetryConfig>): Promise<TelemetryService> {\n const service = getTelemetryService(config)\n await service.initialize(identity)\n return service\n}\n\n/**\n * Create a new installation identity\n */\nexport function createInstallationIdentity(projectName?: string): TelemetryIdentity {\n const installationId = generateInstallationId()\n const identity: TelemetryIdentity = { installationId }\n\n if (projectName) {\n // Generate anonymous project ID\n identity.projectId = generateProjectId(projectName)\n }\n\n return identity\n}\n","/**\n * Route Metadata Service\n *\n * Auto-discovers API routes using Hono's inspectRoutes() and enriches them\n * with metadata from a static registry. Routes without metadata still appear\n * as \"auto-discovered\" — nothing is ever invisible.\n */\n\nimport { inspectRoutes } from 'hono/dev'\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface RouteMetadata {\n method: string\n path: string\n description: string\n authentication: boolean | 'unknown'\n category: string\n documented: boolean\n}\n\ninterface RouteMeta {\n description: string\n authentication: boolean\n category: string\n}\n\nexport interface CategoryInfo {\n title: string\n description: string\n icon: string\n}\n\n// ============================================================================\n// App Instance Storage\n// ============================================================================\n\nlet appInstance: any = null\n\nexport function setAppInstance(app: any): void {\n appInstance = app\n}\n\nexport function getAppInstance(): any {\n return appInstance\n}\n\n// ============================================================================\n// Category Information\n// ============================================================================\n\nexport const CATEGORY_INFO: Record<string, CategoryInfo> = {\n 'Auth': {\n title: 'Authentication',\n description: 'User authentication and authorization endpoints',\n icon: '&#x1f510;'\n },\n 'Content': {\n title: 'Content Management',\n description: 'Content creation, retrieval, and management',\n icon: '&#x1f4dd;'\n },\n 'Media': {\n title: 'Media Management',\n description: 'File upload, storage, and media operations',\n icon: '&#x1f5bc;&#xfe0f;'\n },\n 'Admin': {\n title: 'Admin Interface',\n description: 'Administrative panel and management features',\n icon: '&#x2699;&#xfe0f;'\n },\n 'System': {\n title: 'System',\n description: 'Health checks and system information',\n icon: '&#x1f527;'\n },\n 'Search': {\n title: 'Search',\n description: 'AI-powered search, full-text search, and analytics',\n icon: '&#x1f50d;'\n },\n 'API Keys': {\n title: 'API Keys',\n description: 'API key management and authentication',\n icon: '&#x1f511;'\n },\n 'Workflow': {\n title: 'Workflow',\n description: 'Content workflow and approval processes',\n icon: '&#x1f504;'\n },\n 'Cache': {\n title: 'Cache',\n description: 'Cache management and invalidation',\n icon: '&#x26a1;'\n },\n 'Forms': {\n title: 'Forms',\n description: 'Form submissions and management',\n icon: '&#x1f4cb;'\n },\n 'Files': {\n title: 'Files',\n description: 'File serving from R2 storage',\n icon: '&#x1f4c1;'\n },\n 'Collections': {\n title: 'Collections',\n description: 'Per-collection REST endpoints (auto-generated from registered collections)',\n icon: '&#x1f4da;'\n }\n}\n\n// ============================================================================\n// Route Metadata Registry\n// ============================================================================\n\nconst ROUTE_METADATA: Record<string, RouteMeta> = {\n // Auth endpoints\n 'POST /auth/login': { description: 'Authenticate user with email and password (returns JWT)', category: 'Auth', authentication: false },\n 'POST /auth/login/form': { description: 'Form-based login (sets session cookie)', category: 'Auth', authentication: false },\n 'POST /auth/register': { description: 'Register a new user account', category: 'Auth', authentication: false },\n 'POST /auth/logout': { description: 'Log out the current user and invalidate session', category: 'Auth', authentication: true },\n 'GET /auth/me': { description: 'Get current authenticated user information', category: 'Auth', authentication: true },\n 'POST /auth/refresh': { description: 'Refresh authentication token', category: 'Auth', authentication: true },\n 'POST /auth/seed-admin': { description: 'Create or reset the admin user account', category: 'Auth', authentication: false },\n 'POST /auth/magic-link/request': { description: 'Request a magic link login email', category: 'Auth', authentication: false },\n 'GET /auth/magic-link/verify': { description: 'Verify magic link token and authenticate', category: 'Auth', authentication: false },\n 'POST /auth/otp/request': { description: 'Request a one-time password via email', category: 'Auth', authentication: false },\n 'POST /auth/otp/verify': { description: 'Verify OTP code and authenticate', category: 'Auth', authentication: false },\n\n // Content endpoints\n 'GET /api/collections': { description: 'List all available collections', category: 'Content', authentication: false },\n 'GET /api/collections/:collection/content': { description: 'Get all content items from a specific collection', category: 'Content', authentication: false },\n 'GET /api/content/:id': { description: 'Get a specific content item by ID', category: 'Content', authentication: false },\n 'POST /api/content': { description: 'Create a new content item', category: 'Content', authentication: true },\n 'PUT /api/content/:id': { description: 'Update an existing content item', category: 'Content', authentication: true },\n 'DELETE /api/content/:id': { description: 'Delete a content item', category: 'Content', authentication: true },\n 'GET /api/content/:id/versions': { description: 'Get version history for a content item', category: 'Content', authentication: true },\n 'POST /api/content/:id/restore/:versionId': { description: 'Restore a content item to a previous version', category: 'Content', authentication: true },\n\n // Media endpoints\n 'GET /api/media': { description: 'List all media files with pagination', category: 'Media', authentication: false },\n 'GET /api/media/:id': { description: 'Get a specific media file by ID', category: 'Media', authentication: false },\n 'POST /api/media/upload': { description: 'Upload a new media file to R2 storage', category: 'Media', authentication: true },\n 'DELETE /api/media/:id': { description: 'Delete a media file from storage', category: 'Media', authentication: true },\n\n // Admin API endpoints\n 'GET /admin/api/stats': { description: 'Get dashboard statistics (collections, content, media, users)', category: 'Admin', authentication: true },\n 'GET /admin/api/storage': { description: 'Get storage usage information', category: 'Admin', authentication: true },\n 'GET /admin/api/activity': { description: 'Get recent activity logs', category: 'Admin', authentication: true },\n 'GET /admin/api/collections': { description: 'List all collections with field counts', category: 'Admin', authentication: true },\n 'POST /admin/api/collections': { description: 'Create a new collection', category: 'Admin', authentication: true },\n 'GET /admin/api/collections/:id': { description: 'Get a specific collection with its fields', category: 'Admin', authentication: true },\n 'PATCH /admin/api/collections/:id': { description: 'Update an existing collection', category: 'Admin', authentication: true },\n 'DELETE /admin/api/collections/:id': { description: 'Delete a collection (must be empty)', category: 'Admin', authentication: true },\n 'GET /admin/api/collections/:id/fields': { description: 'Get fields for a specific collection', category: 'Admin', authentication: true },\n 'POST /admin/api/collections/:id/fields': { description: 'Add a field to a collection', category: 'Admin', authentication: true },\n 'PATCH /admin/api/collections/:id/fields/:fieldId': { description: 'Update a collection field', category: 'Admin', authentication: true },\n 'DELETE /admin/api/collections/:id/fields/:fieldId': { description: 'Remove a field from a collection', category: 'Admin', authentication: true },\n 'POST /admin/api/collections/:id/fields/reorder': { description: 'Reorder fields in a collection', category: 'Admin', authentication: true },\n 'GET /admin/api/migrations/status': { description: 'Get database migration status', category: 'Admin', authentication: true },\n 'POST /admin/api/migrations/run': { description: 'Explain how to run D1 migrations with Wrangler', category: 'Admin', authentication: true },\n 'GET /admin/api/content': { description: 'List content items with filtering and pagination', category: 'Admin', authentication: true },\n 'GET /admin/api/content/:id': { description: 'Get a content item for admin editing', category: 'Admin', authentication: true },\n 'POST /admin/api/content': { description: 'Create content via admin API', category: 'Admin', authentication: true },\n 'PUT /admin/api/content/:id': { description: 'Update content via admin API', category: 'Admin', authentication: true },\n 'DELETE /admin/api/content/:id': { description: 'Delete content via admin API', category: 'Admin', authentication: true },\n 'GET /admin/api/media': { description: 'List media files for admin management', category: 'Admin', authentication: true },\n 'POST /admin/api/media/upload': { description: 'Upload media via admin interface', category: 'Admin', authentication: true },\n 'DELETE /admin/api/media/:id': { description: 'Delete media via admin interface', category: 'Admin', authentication: true },\n 'GET /admin/api/users': { description: 'List all users', category: 'Admin', authentication: true },\n 'POST /admin/api/users': { description: 'Create a new user', category: 'Admin', authentication: true },\n 'PUT /admin/api/users/:id': { description: 'Update a user', category: 'Admin', authentication: true },\n 'DELETE /admin/api/users/:id': { description: 'Delete a user', category: 'Admin', authentication: true },\n 'GET /admin/api/logs': { description: 'Get application logs with filtering', category: 'Admin', authentication: true },\n 'GET /admin/api/plugins': { description: 'List all registered plugins', category: 'Admin', authentication: true },\n 'POST /admin/api/plugins/:id/toggle': { description: 'Enable or disable a plugin', category: 'Admin', authentication: true },\n 'GET /admin/api/settings': { description: 'Get application settings', category: 'Admin', authentication: true },\n 'PUT /admin/api/settings': { description: 'Update application settings', category: 'Admin', authentication: true },\n 'GET /admin/api/forms': { description: 'List all forms', category: 'Admin', authentication: true },\n 'GET /admin/api/forms/:id': { description: 'Get form details and submissions', category: 'Admin', authentication: true },\n 'POST /admin/api/forms': { description: 'Create a new form', category: 'Admin', authentication: true },\n 'PUT /admin/api/forms/:id': { description: 'Update a form', category: 'Admin', authentication: true },\n 'DELETE /admin/api/forms/:id': { description: 'Delete a form', category: 'Admin', authentication: true },\n 'GET /admin/api/forms/:id/submissions': { description: 'Get form submissions', category: 'Admin', authentication: true },\n 'DELETE /admin/api/forms/:id/submissions/:submissionId': { description: 'Delete a form submission', category: 'Admin', authentication: true },\n\n // Search endpoints\n 'GET /api/search': { description: 'Search content using AI, FTS5, keyword, or hybrid mode', category: 'Search', authentication: false },\n 'POST /api/search/click': { description: 'Track a search result click for analytics', category: 'Search', authentication: false },\n 'GET /admin/plugins/ai-search/api/status': { description: 'Get search plugin status and configuration', category: 'Search', authentication: true },\n 'POST /admin/plugins/ai-search/api/index': { description: 'Trigger content indexing for search', category: 'Search', authentication: true },\n 'POST /admin/plugins/ai-search/api/index/reset': { description: 'Reset the search index', category: 'Search', authentication: true },\n 'GET /admin/plugins/ai-search/api/analytics': { description: 'Get search analytics and metrics', category: 'Search', authentication: true },\n 'GET /admin/plugins/ai-search/api/analytics/queries': { description: 'Get top search queries', category: 'Search', authentication: true },\n 'GET /admin/plugins/ai-search/api/analytics/clicks': { description: 'Get click-through analytics', category: 'Search', authentication: true },\n 'GET /admin/plugins/ai-search/api/fts5/status': { description: 'Get FTS5 full-text search status', category: 'Search', authentication: true },\n 'POST /admin/plugins/ai-search/api/fts5/rebuild': { description: 'Rebuild the FTS5 search index', category: 'Search', authentication: true },\n 'GET /admin/plugins/ai-search/api/facets': { description: 'Get available search facets', category: 'Search', authentication: true },\n 'GET /admin/plugins/ai-search/api/experiments': { description: 'List search A/B test experiments', category: 'Search', authentication: true },\n 'POST /admin/plugins/ai-search/api/experiments': { description: 'Create a search A/B test experiment', category: 'Search', authentication: true },\n 'GET /admin/plugins/ai-search/api/experiments/:id': { description: 'Get experiment details', category: 'Search', authentication: true },\n 'PUT /admin/plugins/ai-search/api/experiments/:id': { description: 'Update an experiment', category: 'Search', authentication: true },\n 'DELETE /admin/plugins/ai-search/api/experiments/:id': { description: 'Delete an experiment', category: 'Search', authentication: true },\n 'POST /admin/plugins/ai-search/api/experiments/:id/start': { description: 'Start an experiment', category: 'Search', authentication: true },\n 'POST /admin/plugins/ai-search/api/experiments/:id/stop': { description: 'Stop a running experiment', category: 'Search', authentication: true },\n 'GET /admin/plugins/ai-search/api/experiments/:id/results': { description: 'Get experiment results and statistics', category: 'Search', authentication: true },\n 'GET /admin/plugins/ai-search/api/quality': { description: 'Get search quality agent analysis', category: 'Search', authentication: true },\n 'POST /admin/plugins/ai-search/api/quality/run': { description: 'Run search quality analysis', category: 'Search', authentication: true },\n 'GET /admin/plugins/ai-search/api/quality/recommendations': { description: 'Get quality improvement recommendations', category: 'Search', authentication: true },\n 'POST /admin/plugins/ai-search/api/quality/recommendations/:id/apply': { description: 'Apply a quality recommendation', category: 'Search', authentication: true },\n 'POST /admin/plugins/ai-search/api/quality/recommendations/:id/dismiss': { description: 'Dismiss a quality recommendation', category: 'Search', authentication: true },\n 'GET /admin/plugins/ai-search/api/synonyms': { description: 'List search synonyms', category: 'Search', authentication: true },\n 'POST /admin/plugins/ai-search/api/synonyms': { description: 'Add a search synonym', category: 'Search', authentication: true },\n 'DELETE /admin/plugins/ai-search/api/synonyms/:id': { description: 'Delete a search synonym', category: 'Search', authentication: true },\n 'GET /admin/plugins/ai-search/api/query-rules': { description: 'List search query rules', category: 'Search', authentication: true },\n 'POST /admin/plugins/ai-search/api/query-rules': { description: 'Create a query rule', category: 'Search', authentication: true },\n 'PUT /admin/plugins/ai-search/api/query-rules/:id': { description: 'Update a query rule', category: 'Search', authentication: true },\n 'DELETE /admin/plugins/ai-search/api/query-rules/:id': { description: 'Delete a query rule', category: 'Search', authentication: true },\n 'GET /admin/plugins/ai-search/api/settings': { description: 'Get search plugin settings', category: 'Search', authentication: true },\n 'PUT /admin/plugins/ai-search/api/settings': { description: 'Update search plugin settings', category: 'Search', authentication: true },\n\n // API Key endpoints\n 'GET /admin/api-keys/api/keys': { description: 'List all API keys', category: 'API Keys', authentication: true },\n 'POST /admin/api-keys/api/keys': { description: 'Create a new API key', category: 'API Keys', authentication: true },\n 'DELETE /admin/api-keys/api/keys/:id': { description: 'Revoke an API key', category: 'API Keys', authentication: true },\n 'PUT /admin/api-keys/api/keys/:id': { description: 'Update an API key', category: 'API Keys', authentication: true },\n\n // Cache endpoints\n 'GET /admin/cache/api/stats': { description: 'Get cache statistics', category: 'Cache', authentication: true },\n 'POST /admin/cache/api/purge': { description: 'Purge cache entries', category: 'Cache', authentication: true },\n 'GET /admin/cache/api/entries': { description: 'List cache entries', category: 'Cache', authentication: true },\n 'DELETE /admin/cache/api/entries/:key': { description: 'Delete a specific cache entry', category: 'Cache', authentication: true },\n\n // Workflow endpoints\n 'GET /workflow/status/:id': { description: 'Get workflow status for a content item', category: 'Workflow', authentication: true },\n 'POST /workflow/submit/:id': { description: 'Submit content for review', category: 'Workflow', authentication: true },\n 'POST /workflow/approve/:id': { description: 'Approve content in review', category: 'Workflow', authentication: true },\n 'POST /workflow/reject/:id': { description: 'Reject content in review', category: 'Workflow', authentication: true },\n 'POST /workflow/publish/:id': { description: 'Publish approved content', category: 'Workflow', authentication: true },\n 'POST /workflow/unpublish/:id': { description: 'Unpublish content', category: 'Workflow', authentication: true },\n 'GET /workflow/history/:id': { description: 'Get workflow history for a content item', category: 'Workflow', authentication: true },\n\n // Form endpoints (public)\n 'POST /forms/:formId/submit': { description: 'Submit a form (public endpoint)', category: 'Forms', authentication: false },\n 'GET /forms/:formId': { description: 'Get form definition for rendering', category: 'Forms', authentication: false },\n 'POST /api/forms/:formId/submit': { description: 'Submit a form via API', category: 'Forms', authentication: false },\n 'GET /api/forms/:formId': { description: 'Get form definition via API', category: 'Forms', authentication: false },\n\n // System endpoints\n 'GET /health': { description: 'Health check endpoint for monitoring', category: 'System', authentication: false },\n 'GET /api/health': { description: 'API health check with schema information', category: 'System', authentication: false },\n 'GET /api': { description: 'API root - returns API information and available endpoints', category: 'System', authentication: false },\n 'GET /api/system/info': { description: 'Get system information and version', category: 'System', authentication: false },\n 'GET /api/system/schema': { description: 'Get database schema information', category: 'System', authentication: false },\n\n // Collection shorthand routes\n 'GET /api/:collection': { description: 'List items from a collection (shorthand route)', category: 'Collections', authentication: false },\n 'GET /api/:collection/:id': { description: 'Get a single item by ID from a collection', category: 'Collections', authentication: false },\n 'POST /api/:collection': { description: 'Create an item in a collection', category: 'Collections', authentication: true },\n 'PUT /api/:collection/:id': { description: 'Update an item in a collection', category: 'Collections', authentication: true },\n 'DELETE /api/:collection/:id': { description: 'Delete an item from a collection', category: 'Collections', authentication: true },\n\n // File serving\n 'GET /files/*': { description: 'Serve files from R2 storage (public access)', category: 'Files', authentication: false },\n\n // Database tools\n 'POST /admin/database-tools/api/query': { description: 'Execute a database query', category: 'Admin', authentication: true },\n 'GET /admin/database-tools/api/tables': { description: 'List database tables', category: 'Admin', authentication: true },\n 'GET /admin/database-tools/api/tables/:name': { description: 'Get table schema and sample data', category: 'Admin', authentication: true },\n\n // Seed data\n 'POST /admin/seed-data/api/generate': { description: 'Generate seed data for development', category: 'Admin', authentication: true },\n 'GET /admin/seed-data/api/status': { description: 'Get seed data generation status', category: 'Admin', authentication: true },\n\n // Email plugin\n 'POST /admin/plugins/email/api/send': { description: 'Send an email', category: 'Admin', authentication: true },\n 'GET /admin/plugins/email/api/templates': { description: 'List email templates', category: 'Admin', authentication: true },\n 'POST /admin/plugins/email/api/test': { description: 'Send a test email', category: 'Admin', authentication: true },\n}\n\n// ============================================================================\n// Whitelist Patterns for API routes\n// ============================================================================\n\nconst INCLUDED_ROUTE_PATTERNS: RegExp[] = [\n /^\\/api\\//, // All /api/* routes\n /^\\/api$/, // API root\n /^\\/auth\\/(?!login$|register$)/, // Auth routes except GET login/register HTML pages\n /^\\/auth\\/login$/, // POST /auth/login (method filtered later)\n /^\\/auth\\/register$/, // POST /auth/register (method filtered later)\n /^\\/admin\\/api\\//, // Admin API endpoints\n /^\\/admin\\/api-keys\\/api\\//, // API key management\n /^\\/admin\\/cache\\/api\\//, // Cache management API\n /^\\/admin\\/plugins\\/.*\\/api\\//, // Plugin API endpoints\n /^\\/admin\\/database-tools\\/api\\//, // Database tools API\n /^\\/admin\\/seed-data\\/api\\//, // Seed data API\n /^\\/workflow\\//, // Workflow endpoints\n /^\\/health$/, // Health check\n /^\\/files\\//, // File serving\n /^\\/forms\\//, // Public form endpoints\n]\n\n// Routes to always exclude (even if they match an include pattern)\nconst EXCLUDED_ROUTES = new Set([\n 'GET /auth/login',\n 'GET /auth/register',\n 'GET /auth/login/form',\n])\n\n// ============================================================================\n// Route Discovery\n// ============================================================================\n\nlet cachedRouteList: RouteMetadata[] | null = null\n\nfunction isIncludedRoute(method: string, path: string): boolean {\n // Check exclusions first\n const key = `${method} ${path}`\n if (EXCLUDED_ROUTES.has(key)) {\n return false\n }\n\n // Check if the path matches any include pattern\n return INCLUDED_ROUTE_PATTERNS.some(pattern => pattern.test(path))\n}\n\nfunction inferCategory(path: string): string {\n if (path.startsWith('/auth/')) return 'Auth'\n if (path.startsWith('/api/search')) return 'Search'\n if (path.startsWith('/api/media')) return 'Media'\n if (path.startsWith('/api/system')) return 'System'\n if (path.startsWith('/api/content') || path.startsWith('/api/collections')) return 'Content'\n if (path.startsWith('/api/forms')) return 'Forms'\n if (path.startsWith('/admin/api-keys')) return 'API Keys'\n if (path.startsWith('/admin/cache')) return 'Cache'\n if (path.startsWith('/admin/plugins/ai-search')) return 'Search'\n if (path.startsWith('/admin/api')) return 'Admin'\n if (path.startsWith('/admin/database-tools')) return 'Admin'\n if (path.startsWith('/admin/seed-data')) return 'Admin'\n if (path.startsWith('/admin/plugins/email')) return 'Admin'\n if (path.startsWith('/workflow/')) return 'Workflow'\n if (path.startsWith('/forms/')) return 'Forms'\n if (path.startsWith('/files/')) return 'Files'\n if (path === '/health' || path.startsWith('/api')) return 'System'\n if (path.match(/^\\/api\\/[^/]+(\\/:id)?$/) && !path.startsWith('/api/content') && !path.startsWith('/api/collections') && !path.startsWith('/api/media') && !path.startsWith('/api/search') && !path.startsWith('/api/system') && !path.startsWith('/api/health') && !path.startsWith('/api/documents') && !path.startsWith('/api/forms')) return 'Collections'\n return 'Other'\n}\n\nfunction inferAuth(path: string): boolean | 'unknown' {\n // Known public routes\n if (path === '/health' || path === '/api' || path === '/api/health') return false\n if (path === '/api/system/info' || path === '/api/system/schema') return false\n if (path.startsWith('/files/')) return false\n if (path.startsWith('/forms/') || path.startsWith('/api/forms/')) return false\n\n // Admin routes require auth\n if (path.startsWith('/admin/')) return true\n if (path.startsWith('/workflow/')) return true\n\n return 'unknown'\n}\n\nexport function buildRouteList(app: any): RouteMetadata[] {\n if (cachedRouteList) return cachedRouteList\n\n if (!app) return []\n\n try {\n const routes = inspectRoutes(app as any)\n\n // Deduplicate and filter\n const seen = new Set<string>()\n const result: RouteMetadata[] = []\n\n for (const route of routes) {\n // Skip middleware entries\n if (route.isMiddleware) continue\n // Skip ALL method (middleware-like catch-all)\n if (route.method === 'ALL') continue\n\n const key = `${route.method} ${route.path}`\n\n // Skip duplicates\n if (seen.has(key)) continue\n seen.add(key)\n\n // Apply whitelist filter\n if (!isIncludedRoute(route.method, route.path)) continue\n\n // Look up metadata\n const meta = ROUTE_METADATA[key]\n\n if (meta) {\n result.push({\n method: route.method,\n path: route.path,\n description: meta.description,\n authentication: meta.authentication,\n category: meta.category,\n documented: true\n })\n } else {\n // Auto-discovered: infer category and auth\n result.push({\n method: route.method,\n path: route.path,\n description: '',\n authentication: inferAuth(route.path),\n category: inferCategory(route.path),\n documented: false\n })\n }\n }\n\n // Sort: by category, then method order, then path\n const methodOrder: Record<string, number> = { GET: 0, POST: 1, PUT: 2, PATCH: 3, DELETE: 4 }\n result.sort((a, b) => {\n const catCmp = a.category.localeCompare(b.category)\n if (catCmp !== 0) return catCmp\n const methCmp = (methodOrder[a.method] ?? 5) - (methodOrder[b.method] ?? 5)\n if (methCmp !== 0) return methCmp\n return a.path.localeCompare(b.path)\n })\n\n cachedRouteList = result\n return result\n } catch (error) {\n console.error('Failed to inspect routes:', error)\n return []\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/services/document-type-registry.ts","../src/services/document-types-seed.ts","../src/middleware/bootstrap.ts","../src/middleware/auth.ts","../src/middleware/metrics.ts","../src/middleware/csrf.ts","../src/middleware/rate-limit.ts","../src/middleware/security-headers.ts","../src/middleware/plugin-middleware.ts","../src/middleware/index.ts"],"names":["RbacService","result","JWT_SECRET_FALLBACK","getCookie","setCookie"],"mappings":"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","file":"chunk-GVHST4D7.js","sourcesContent":["import { D1Database } from '@cloudflare/workers-types'\nimport { nanoid } from 'nanoid'\nimport type {\n PluginDocumentType,\n DocumentType,\n DocumentTypeRow,\n} from '../schemas/document'\nimport { ensureScalarSchema } from './document-scalar-schema'\n\nfunction rowToDocumentType(row: DocumentTypeRow): DocumentType {\n return {\n id: row.id,\n name: row.name,\n displayName: row.display_name,\n description: row.description,\n schema: JSON.parse(row.schema),\n queryableFields: JSON.parse(row.queryable_fields),\n settings: JSON.parse(row.settings),\n pluginId: row.plugin_id,\n source: row.source,\n schemaVersion: row.schema_version,\n isSystem: row.is_system === 1,\n isActive: row.is_active === 1,\n isAuth: row.is_auth === 1,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n }\n}\n\nexport class DocumentTypeRegistry {\n private cache = new Map<string, DocumentType>()\n\n constructor(private db: D1Database) {}\n\n // Register or update a document type. Idempotent: bumps schema_version only when schema changes.\n async register(def: PluginDocumentType & { pluginId?: string; source?: 'code' | 'plugin' | 'system' }): Promise<DocumentType> {\n const now = Math.floor(Date.now() / 1000)\n const existing = await this.findById(def.id)\n\n // A z.ZodSchema is not JSON-serializable, so persist a stable serializable shape derived from\n // the type's queryable fields + settings. This is what schemaChanged compares, so schema_version\n // bumps whenever a type's filterable shape changes (and is stamped onto documents.type_version).\n const schemaJson = JSON.stringify({ queryableFields: def.queryableFields ?? [], settings: def.settings ?? {} })\n const queryableJson = JSON.stringify(def.queryableFields ?? [])\n const settingsJson = JSON.stringify(def.settings ?? {})\n\n if (existing) {\n const schemaChanged = schemaJson !== JSON.stringify(existing.schema)\n const newVersion = schemaChanged ? existing.schemaVersion + 1 : existing.schemaVersion\n\n await this.db\n .prepare(\n `UPDATE document_types SET\n display_name = ?,\n description = ?,\n schema = ?,\n queryable_fields = ?,\n settings = ?,\n plugin_id = ?,\n schema_version = ?,\n is_active = 1,\n is_auth = ?,\n updated_at = ?\n WHERE id = ?`,\n )\n .bind(\n def.displayName,\n def.description ?? null,\n schemaJson,\n queryableJson,\n settingsJson,\n def.pluginId ?? null,\n newVersion,\n def.isAuth ? 1 : 0,\n now,\n def.id,\n )\n .run()\n\n // Auto-DDL: ensure VIRTUAL generated columns + indexes for scalar fields.\n await ensureScalarSchema(this.db, def.id, def.queryableFields ?? [])\n\n const updated = await this.findById(def.id)\n this.cache.set(def.id, updated!)\n return updated!\n }\n\n await this.db\n .prepare(\n `INSERT INTO document_types (id, name, display_name, description, schema, queryable_fields, settings, plugin_id, source, schema_version, is_system, is_active, is_auth, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 1, 0, 1, ?, ?, ?)`,\n )\n .bind(\n def.id,\n def.name ?? def.id,\n def.displayName,\n def.description ?? null,\n schemaJson,\n queryableJson,\n settingsJson,\n def.pluginId ?? null,\n def.source ?? 'code',\n def.isAuth ? 1 : 0,\n now,\n now,\n )\n .run()\n\n // Auto-DDL: ensure VIRTUAL generated columns + indexes for scalar fields.\n await ensureScalarSchema(this.db, def.id, def.queryableFields ?? [])\n\n const created = await this.findById(def.id)\n this.cache.set(def.id, created!)\n return created!\n }\n\n async findById(id: string): Promise<DocumentType | null> {\n if (this.cache.has(id)) return this.cache.get(id)!\n\n const row = await this.db\n .prepare('SELECT * FROM document_types WHERE id = ?')\n .bind(id)\n .first<DocumentTypeRow>()\n\n if (!row) return null\n const dt = rowToDocumentType(row)\n this.cache.set(id, dt)\n return dt\n }\n\n async findAll(activeOnly = true): Promise<DocumentType[]> {\n const sql = activeOnly\n ? 'SELECT * FROM document_types WHERE is_active = 1 ORDER BY name'\n : 'SELECT * FROM document_types ORDER BY name'\n\n const result = await this.db.prepare(sql).all<DocumentTypeRow>()\n return (result.results ?? []).map(rowToDocumentType)\n }\n\n async deactivate(id: string): Promise<void> {\n const now = Math.floor(Date.now() / 1000)\n await this.db\n .prepare('UPDATE document_types SET is_active = 0, updated_at = ? WHERE id = ?')\n .bind(now, id)\n .run()\n this.cache.delete(id)\n }\n\n clearCache(): void {\n this.cache.clear()\n }\n}\n","import { D1Database } from '@cloudflare/workers-types'\nimport { z } from 'zod'\nimport { DocumentTypeRegistry } from './document-type-registry'\nimport { getCollectionRegistry } from './collection-registry'\n\n// Passthrough schema: accepts any JSON object for POC types.\n// Individual fields are validated at the queryable-field level; the full\n// payload schema is a future enhancement (addDocumentType will accept Zod schemas).\nconst anyObject = z.record(z.string(), z.unknown())\n\n// Registers the POC document types idempotently during bootstrap.\n// These are the candidate types from the document model plan.\n// Each call is a no-op if the type already exists and the schema hasn't changed.\nexport async function bootstrapDocumentTypes(db: D1Database): Promise<void> {\n const registry = new DocumentTypeRegistry(db)\n\n // Site settings: internal singleton config — never surfaced in content admin.\n await registry.register({\n id: 'site_settings',\n name: 'site_settings',\n displayName: 'Site Settings',\n description: 'Global site configuration (internal; managed via admin settings UI)',\n source: 'system',\n schema: anyObject,\n settings: {\n internal: true,\n maxVersionsPerRoot: 1,\n baseGrants: { admin: ['read', 'create', 'update', 'delete', 'manage'] },\n },\n queryableFields: [],\n })\n\n // Blog post: the code-managed `blog_post` collection is backed by the document model.\n // The matching id (`blog_post` == collection name) is how content admin detects doc-backing.\n await registry.register({\n id: 'blog_post',\n name: 'blog_post',\n displayName: 'Blog Post',\n description: 'Blog post (document-backed; edited via the content collection UI)',\n source: 'system',\n schema: anyObject,\n settings: {\n baseGrants: { public: ['read'], admin: ['read', 'create', 'update', 'delete', 'publish', 'manage'], editor: ['read', 'create', 'update', 'publish'], viewer: ['read'] },\n maxVersionsPerRoot: 50,\n },\n queryableFields: [\n { name: 'difficulty', kind: 'scalar', type: 'text', column: 'q_blog_difficulty' },\n { name: 'author', kind: 'scalar', type: 'text', column: 'q_blog_author' },\n ],\n })\n\n // Plugin registry (document-backed plugin management)\n await registry.register({\n id: 'plugin',\n name: 'plugin',\n displayName: 'Plugin',\n description: 'System plugin record (managed by the plugin bootstrap service)',\n source: 'system',\n schema: anyObject,\n settings: {\n baseGrants: { admin: ['read', 'create', 'update', 'delete', 'publish', 'manage'] },\n maxVersionsPerRoot: 1,\n internal: true,\n },\n queryableFields: [\n { name: 'status', kind: 'scalar', type: 'text', column: 'q_plugin_status' },\n { name: 'category', kind: 'scalar', type: 'text', column: 'q_plugin_category' },\n { name: 'isCore', kind: 'scalar', type: 'integer', column: 'q_plugin_is_core' },\n ],\n })\n\n // Tenant registry (document-backed multi-tenancy; rows managed by the multi-tenant plugin).\n // Tenant records are platform metadata and live under the 'default' tenant themselves.\n // Zero rows until the multi-tenant plugin is activated and used.\n await registry.register({\n id: 'tenant',\n name: 'tenant',\n displayName: 'Tenant',\n description: 'Tenant record (managed by the multi-tenant plugin; slug = tenant id)',\n source: 'system',\n schema: anyObject,\n settings: {\n baseGrants: { admin: ['read', 'create', 'update', 'delete', 'manage'] },\n maxVersionsPerRoot: 1,\n internal: true,\n },\n queryableFields: [\n { name: 'status', kind: 'scalar', type: 'text', column: 'q_tenant_status' },\n { name: 'domain', kind: 'scalar', type: 'text', column: 'q_tenant_domain' },\n ],\n })\n\n // User profile (auth-owned). One document per user, addressed by slug = userId.\n // Replaces the auth_user_profiles table. Typed fields + custom fields live in `data`.\n await registry.register({\n id: 'user_profile',\n name: 'user_profile',\n displayName: 'User Profile',\n description: 'Per-user profile record (auth-owned; one document per user, slug = userId)',\n source: 'system',\n isAuth: true,\n schema: anyObject,\n settings: {\n // Hidden from the content admin surfaces; a single mutable record (no version history).\n internal: true,\n maxVersionsPerRoot: 1,\n pii: true,\n baseGrants: { admin: ['read', 'create', 'update', 'delete', 'manage'] },\n },\n queryableFields: [],\n })\n\n // Media asset (document-authoritative media library). One document per uploaded R2 object.\n // Internal: managed via the media library + media selector, not offered as a content model.\n // Registering here both satisfies the documents.type_id FK and creates the q_media_* columns\n // (DocumentTypeRegistry.register → ensureScalarSchema). Must stay in sync with MEDIA_QUERYABLE\n // in services/media-documents.ts.\n await registry.register({\n id: 'media_asset',\n name: 'media_asset',\n displayName: 'Media Asset',\n description: 'Uploaded media file metadata (managed via the media library; backs an R2 object)',\n source: 'system',\n schema: anyObject,\n settings: {\n internal: true,\n maxVersionsPerRoot: 5,\n baseGrants: {\n admin: ['read', 'create', 'update', 'delete', 'manage'],\n editor: ['read', 'create', 'update'],\n author: ['read', 'create'],\n viewer: ['read'],\n },\n },\n queryableFields: [\n { name: 'mimeType', kind: 'scalar', type: 'text', column: 'q_media_mime' },\n { name: 'folder', kind: 'scalar', type: 'text', column: 'q_media_folder' },\n { name: 'size', kind: 'scalar', type: 'integer', column: 'q_media_size' },\n { name: 'tags', kind: 'facet', type: 'text' },\n ],\n })\n\n // Plugin activity log (document-backed; replaces legacy plugin_activity_log table which was never migrated)\n await registry.register({\n id: 'plugin_activity',\n name: 'plugin_activity',\n displayName: 'Plugin Activity',\n description: 'Plugin lifecycle event log (installed/activated/deactivated/settings_updated/error)',\n source: 'system',\n schema: anyObject,\n settings: {\n internal: true,\n maxVersionsPerRoot: 1,\n baseGrants: { admin: ['read', 'create', 'manage'] },\n },\n queryableFields: [\n { name: 'pluginId', kind: 'scalar', type: 'text', column: 'q_plugin_activity_plugin_id' },\n { name: 'action', kind: 'scalar', type: 'text', column: 'q_plugin_activity_action' },\n ],\n })\n\n // Security audit event (document-backed; replaces legacy security_events table)\n await registry.register({\n id: 'security_event',\n name: 'security_event',\n displayName: 'Security Event',\n description: 'Security audit event (login attempts, lockouts, suspicious activity)',\n source: 'system',\n schema: anyObject,\n settings: {\n internal: true,\n maxVersionsPerRoot: 1,\n baseGrants: { admin: ['read', 'create', 'manage'] },\n },\n queryableFields: [\n { name: 'eventType', kind: 'scalar', type: 'text', column: 'q_sa_event_type' },\n { name: 'severity', kind: 'scalar', type: 'text', column: 'q_sa_severity' },\n { name: 'userId', kind: 'scalar', type: 'text', column: 'q_sa_user_id' },\n { name: 'email', kind: 'scalar', type: 'text', column: 'q_sa_email' },\n { name: 'ipAddress', kind: 'scalar', type: 'text', column: 'q_sa_ip_address' },\n { name: 'blocked', kind: 'scalar', type: 'integer', column: 'q_sa_blocked' },\n ],\n })\n\n // Analytics event (document-backed; replaces legacy analytics_events table)\n await registry.register({\n id: 'analytics_event',\n name: 'analytics_event',\n displayName: 'Analytics Event',\n description: 'Tracked analytics event (page view, user action, custom event)',\n source: 'system',\n schema: anyObject,\n settings: {\n internal: true,\n maxVersionsPerRoot: 1,\n baseGrants: { admin: ['read', 'create', 'manage'] },\n },\n queryableFields: [\n { name: 'event', kind: 'scalar', type: 'text', column: 'q_evt_event' },\n { name: 'category', kind: 'scalar', type: 'text', column: 'q_evt_category' },\n { name: 'userId', kind: 'scalar', type: 'text', column: 'q_evt_user_id' },\n { name: 'sessionId', kind: 'scalar', type: 'text', column: 'q_evt_session_id' },\n { name: 'path', kind: 'scalar', type: 'text', column: 'q_evt_path' },\n ],\n })\n\n // Media asset: every file upload creates a media_asset document (document-authoritative).\n // File bytes stay in R2; this document holds intrinsic metadata (dimensions, mime, r2Key…).\n await registry.register({\n id: 'media_asset',\n name: 'media_asset',\n displayName: 'Media Asset',\n description: 'Media file metadata (R2 object key + intrinsic properties; URL derived at read time)',\n source: 'system',\n schema: anyObject,\n settings: {\n baseGrants: { public: ['read'], admin: ['read', 'create', 'update', 'delete', 'publish', 'manage'], editor: ['read', 'create', 'update'] },\n maxVersionsPerRoot: 5,\n },\n queryableFields: [\n { name: 'mimeType', kind: 'scalar', type: 'text', column: 'q_media_mime' },\n { name: 'folder', kind: 'scalar', type: 'text', column: 'q_media_folder' },\n { name: 'size', kind: 'scalar', type: 'integer', column: 'q_media_size' },\n { name: 'tags', kind: 'facet', type: 'text' },\n ],\n })\n\n // ── RBAC (auth-owned). 3 document types replace 4 relational tables: ──────────\n // rbac_role slug = roleId, data.grants[] embedded (replaces role_grants)\n // rbac_verb slug = verbId\n // rbac_user_roles slug = userId, data.roleIds[] embedded (replaces user_roles)\n // All internal + is_auth so they never surface in content. See services/rbac.ts.\n for (const [id, displayName, description] of [\n ['rbac_role', 'RBAC Role', 'Role record with embedded grants (auth-owned)'],\n ['rbac_verb', 'RBAC Verb', 'Permission verb (auth-owned)'],\n ['rbac_user_roles', 'RBAC User Roles', \"Per-user role assignments (auth-owned; slug = userId)\"],\n ] as const) {\n await registry.register({\n id,\n name: id,\n displayName,\n description,\n source: 'system',\n isAuth: true,\n schema: anyObject,\n settings: {\n internal: true,\n maxVersionsPerRoot: 1,\n baseGrants: { admin: ['read', 'create', 'update', 'delete', 'manage'] },\n },\n queryableFields: [],\n })\n }\n}\n\n/**\n * Register a document type for every code-defined collection in the registry.\n *\n * Code-defined collections become document-backed automatically so that all\n * content writes against them flow through the documents repository. The\n * document type's id == collection name, matching how content admin detects\n * doc-backing.\n */\nexport async function autoRegisterCollectionDocumentTypes(db: D1Database): Promise<string[]> {\n const registry = new DocumentTypeRegistry(db)\n const collections = getCollectionRegistry().listActive()\n const registered: string[] = []\n\n for (const collection of collections) {\n // Skip system/internal collections that already have explicit document type\n // definitions in bootstrapDocumentTypes (e.g. blog_post is seeded above\n // with its own queryable fields). The explicit registration wins.\n if (collection.internal) continue\n if (collection.name === 'blog_post') continue\n\n try {\n await registry.register({\n id: collection.name,\n name: collection.name,\n displayName: collection.displayName,\n description: collection.description,\n source: 'system',\n schema: anyObject,\n settings: {\n baseGrants: {\n public: ['read'],\n admin: ['read', 'create', 'update', 'delete', 'publish', 'manage'],\n editor: ['read', 'create', 'update', 'publish'],\n viewer: ['read'],\n },\n maxVersionsPerRoot: 50,\n ...(collection.versioning ? { versioning: true } : {}),\n },\n queryableFields: [],\n })\n registered.push(collection.name)\n } catch (error) {\n console.error(`[document-types-seed] Failed to register collection \"${collection.name}\":`, error)\n }\n }\n\n return registered\n}\n","import { Context, Next } from \"hono\";\nimport { loadCollectionConfigs } from \"../services/collection-loader\";\nimport { getCollectionRegistry } from \"../services/collection-registry\";\nimport { MigrationService } from \"../services/migrations\";\nimport { PluginBootstrapService } from \"../services/plugin-bootstrap\";\nimport { bootstrapDocumentTypes, autoRegisterCollectionDocumentTypes } from \"../services/document-types-seed\";\nimport { getHookSystem, hasHookSystem } from \"../plugins/hooks/hook-system-singleton\";\nimport type { SonicJSConfig } from \"../app\";\n\ntype Bindings = {\n DB: D1Database;\n KV: KVNamespace;\n JWT_SECRET?: string;\n CORS_ORIGINS?: string;\n ENVIRONMENT?: string;\n};\n\n// Track if bootstrap has been run in this worker instance\nlet bootstrapComplete = false;\n\n/**\n * Verify security-critical environment configuration at startup.\n * Logs warnings in development, throws in production to prevent\n * insecure deployments from silently running.\n */\nexport function verifySecurityConfig(env: Bindings): void {\n const warnings: string[] = [];\n\n // Check JWT secret\n if (!env.JWT_SECRET) {\n warnings.push(\n \"JWT_SECRET is not set — using hardcoded fallback. Set via `wrangler secret put JWT_SECRET`\"\n );\n } else if (env.JWT_SECRET.includes(\"change-in-production\")) {\n warnings.push(\n \"JWT_SECRET contains the default value — tokens are forgeable. Generate a strong random secret\"\n );\n }\n\n // Check CORS origins\n if (!env.CORS_ORIGINS) {\n warnings.push(\n \"CORS_ORIGINS is not set — all cross-origin API requests will be rejected\"\n );\n }\n\n // Check environment designation\n if (!env.ENVIRONMENT) {\n warnings.push(\n \"ENVIRONMENT is not set — HSTS header will not be applied. Set to \\\"production\\\" or \\\"development\\\"\"\n );\n }\n\n if (warnings.length === 0) {\n return;\n }\n\n const isProduction = env.ENVIRONMENT === \"production\";\n\n for (const warning of warnings) {\n console.warn(`[SonicJS Security] ${warning}`);\n }\n\n if (isProduction) {\n // In production, a missing or default JWT_SECRET is a hard failure —\n // every token issued would be forgeable by anyone reading the source code.\n const hasCritical =\n !env.JWT_SECRET || env.JWT_SECRET.includes(\"change-in-production\");\n if (hasCritical) {\n throw new Error(\n \"[SonicJS Security] CRITICAL: Production deployment is missing a secure JWT_SECRET. \" +\n \"Set it via `wrangler secret put JWT_SECRET` before deploying.\"\n );\n }\n }\n}\n\n/**\n * Bootstrap middleware that ensures system initialization\n * Runs once per worker instance\n */\nexport function bootstrapMiddleware(config: SonicJSConfig = {}) {\n return async (c: Context<{ Bindings: Bindings; Variables: { hookSystem?: unknown } }>, next: Next) => {\n // Attach the hook system to the request BEFORE any heavy bootstrap work\n // runs, so anything that emits a hook during bootstrap (cron cold starts,\n // RBAC seed, document-type registration, plugin onBoot via createPluginWirer)\n // sees a live bus instead of a no-op. The process singleton was published at\n // app-factory time (app.ts); we only forward it onto the request here.\n if (hasHookSystem()) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Variables typed loosely here; concrete type lives in app.ts\n (c as any).set(\"hookSystem\", getHookSystem());\n }\n\n // Skip if already bootstrapped in this worker instance\n if (bootstrapComplete) {\n return next();\n }\n\n // Skip bootstrap for static assets and health checks\n const path = c.req.path;\n if (\n path.startsWith(\"/images/\") ||\n path.startsWith(\"/assets/\") ||\n path === \"/health\" ||\n path.endsWith(\".js\") ||\n path.endsWith(\".css\") ||\n path.endsWith(\".png\") ||\n path.endsWith(\".jpg\") ||\n path.endsWith(\".ico\")\n ) {\n return next();\n }\n\n try {\n console.log(\"[Bootstrap] Starting system initialization...\");\n\n // 1. Run idempotent schema compatibility repairs. Migration state and\n // migration execution are owned by Cloudflare D1/Wrangler.\n console.log(\"[Bootstrap] Checking schema compatibility...\");\n const migrationService = new MigrationService(c.env.DB);\n await migrationService.ensureSchemaCompatibility();\n\n // 1a. Wire the CACHE_KV binding into the cache plugin's singleton store so\n // cache writes survive isolate evictions. Memory-only cache is per-isolate\n // and ephemeral, which makes /admin/cache appear \"empty\" after restarts.\n try {\n const kv = (c.env as any).CACHE_KV;\n if (kv) {\n const { setGlobalKVNamespace } = await import(\n \"../plugins/cache/services/cache\"\n );\n setGlobalKVNamespace(kv);\n }\n } catch (error) {\n console.error(\"[Bootstrap] Error wiring CACHE_KV namespace:\", error);\n }\n\n // 2. Populate the in-memory collection registry from code-defined configs.\n // This is the source of truth going forward; the DB `collections` table is\n // being decommissioned (see docs/ai/plans/drop-db-collections-plan.md).\n console.log(\"[Bootstrap] Populating collection registry...\");\n try {\n const configs = await loadCollectionConfigs();\n getCollectionRegistry().register(configs);\n console.log(`[Bootstrap] Registry populated with ${configs.length} collection(s)`);\n } catch (error) {\n console.error(\"[Bootstrap] Error populating collection registry:\", error);\n }\n\n // 3. Register document types (idempotent)\n console.log(\"[Bootstrap] Registering document types...\");\n try {\n await bootstrapDocumentTypes(c.env.DB);\n } catch (error) {\n console.error(\"[Bootstrap] Error registering document types:\", error);\n }\n\n // 2c. Repair legacy users that have password_hash in auth_user but no\n // auth_account credential row (registered before Better Auth migration).\n try {\n await repairMissingCredentialAccounts(c.env.DB)\n } catch (error) {\n console.error('[Bootstrap] Error repairing credential accounts:', error)\n }\n\n // 3a. Seed system RBAC roles/verbs/grants as documents (idempotent).\n try {\n const { RbacService } = await import(\"../services/rbac\");\n await new RbacService(c.env.DB, (c.env as any).CACHE_KV).ensureSystemRbacSeed();\n } catch (error) {\n console.error(\"[Bootstrap] Error seeding RBAC documents:\", error);\n }\n\n // 3b. Make every content collection document-backed (so all new content goes to `documents`).\n try {\n const auto = await autoRegisterCollectionDocumentTypes(c.env.DB);\n if (auto.length) console.log(`[Bootstrap] Document-backed collections registered: ${auto.join(\", \")}`);\n } catch (error) {\n console.error(\"[Bootstrap] Error auto-registering collection document types:\", error);\n }\n\n // 4. Bootstrap core plugins (unless disableAll is set)\n if (!config.plugins?.disableAll) {\n console.log(\"[Bootstrap] Bootstrapping core plugins...\");\n const bootstrapService = new PluginBootstrapService(c.env.DB);\n\n // Check if bootstrap is needed\n const needsBootstrap = await bootstrapService.isBootstrapNeeded();\n if (needsBootstrap) {\n await bootstrapService.bootstrapCorePlugins();\n }\n } else {\n console.log(\"[Bootstrap] Plugin bootstrap skipped (disableAll is true)\");\n }\n\n // Mark bootstrap as complete for this worker instance\n bootstrapComplete = true;\n console.log(\"[Bootstrap] System initialization completed\");\n } catch (error) {\n console.error(\"[Bootstrap] Error during system initialization:\", error);\n // Don't prevent the app from starting, but log the error\n }\n\n // 4. Verify security configuration (outside try/catch so critical\n // errors in production propagate and prevent insecure deployments)\n verifySecurityConfig(c.env as Bindings);\n\n return next();\n };\n}\n\n/**\n * Reset bootstrap flag (useful for testing)\n */\nexport function resetBootstrap() {\n bootstrapComplete = false;\n}\n\n/**\n * Find auth_user rows that have a password_hash but no auth_account credential\n * row (created before Better Auth migration) and repair them. Idempotent —\n * INSERT OR IGNORE means re-runs are safe.\n */\nasync function repairMissingCredentialAccounts(db: D1Database): Promise<void> {\n const { results } = await db.prepare(`\n SELECT u.id, u.password_hash\n FROM auth_user u\n WHERE u.password_hash IS NOT NULL AND u.password_hash != ''\n AND NOT EXISTS (\n SELECT 1 FROM auth_account a\n WHERE a.user_id = u.id AND a.provider_id = 'credential'\n )\n `).all()\n\n if (!results.length) return\n\n console.log(`[Bootstrap] Repairing ${results.length} user(s) missing credential auth_account rows`)\n const nowSec = Math.floor(Date.now() / 1000)\n for (const user of results as Array<{ id: string; password_hash: string }>) {\n await db.prepare(`\n INSERT OR IGNORE INTO auth_account (id, user_id, account_id, provider_id, password, created_at, updated_at)\n VALUES (?, ?, ?, 'credential', ?, ?, ?)\n `).bind(`cred-${user.id}`, user.id, user.id, user.password_hash, nowSec, nowSec).run()\n }\n console.log(`[Bootstrap] Credential account repair complete (${results.length} repaired)`)\n}\n","import { sign, verify } from 'hono/jwt'\nimport { Context, Next } from 'hono'\nimport { getCookie, setCookie } from 'hono/cookie'\nimport { RbacService } from '../services/rbac'\n\ntype JWTPayload = {\n userId: string\n email: string\n role: string\n exp: number\n iat: number\n}\n\n// Fallback JWT secret for local development only (no wrangler secret set)\nconst JWT_SECRET_FALLBACK = 'your-super-secret-jwt-key-change-in-production'\n\n// Default JWT TTL: 30 days. Can be overridden via JWT_EXPIRES_IN env var.\nconst DEFAULT_JWT_EXPIRES_IN_SECONDS = 60 * 60 * 24 * 30\n\n/**\n * Parse a TTL string like \"30d\", \"12h\", \"3600s\", or a bare number-of-seconds\n * into a seconds value. Returns null if the input is missing/unparseable.\n */\nfunction parseDuration(input: string | number | undefined | null): number | null {\n if (input === undefined || input === null || input === '') return null\n if (typeof input === 'number' && Number.isFinite(input) && input > 0) {\n return Math.floor(input)\n }\n const raw = String(input).trim()\n if (/^\\d+$/.test(raw)) {\n const n = parseInt(raw, 10)\n return n > 0 ? n : null\n }\n const match = raw.match(/^(\\d+)\\s*(s|sec|secs|seconds|m|min|mins|minutes|h|hr|hrs|hours|d|day|days)$/i)\n if (!match) return null\n const value = parseInt(match[1]!, 10)\n const unit = match[2]!.toLowerCase()\n if (unit.startsWith('s')) return value\n if (unit.startsWith('m')) return value * 60\n if (unit.startsWith('h')) return value * 60 * 60\n if (unit.startsWith('d')) return value * 60 * 60 * 24\n return null\n}\n\n/**\n * Resolve the JWT expiry in seconds from the environment.\n * Honors `JWT_EXPIRES_IN` (seconds or \"30d\"/\"12h\"/\"3600s\") with a 30-day default.\n */\nexport function getJwtExpirySeconds(env?: Record<string, any> | null): number {\n const configured = parseDuration(env?.JWT_EXPIRES_IN)\n return configured ?? DEFAULT_JWT_EXPIRES_IN_SECONDS\n}\n\n/**\n * Resolve the JWT expiry in seconds. Precedence: `JWT_EXPIRES_IN` env var\n * (authoritative ceiling) → `settings.security.jwtExpiresIn` DB value\n * (admin-configurable) → 30-day default.\n *\n * The env var wins so operators can cap runtime overrides — admins can adjust\n * the TTL from /admin/settings/security, but an env var, if set, always wins.\n * DB failures fall back to env/default so auth never breaks if the settings\n * table is unreachable.\n */\nexport async function getJwtExpirySecondsFromDb(\n db: { prepare: (query: string) => any } | null | undefined,\n env?: Record<string, any> | null\n): Promise<number> {\n const envParsed = parseDuration(env?.JWT_EXPIRES_IN)\n if (envParsed) return envParsed\n\n if (db) {\n try {\n const row = await db\n .prepare(\"SELECT data FROM documents WHERE type_id = 'site_settings' AND slug = 'security' AND tenant_id = 'default' AND is_current_draft = 1 AND deleted_at IS NULL\")\n .first() as { data: string } | null\n if (row?.data) {\n const data = JSON.parse(row.data)\n const parsed = parseDuration(data.jwtExpiresIn)\n if (parsed) return parsed\n }\n } catch (err) {\n console.warn('Failed to read jwtExpiresIn from settings, falling back to default:', err)\n }\n }\n return DEFAULT_JWT_EXPIRES_IN_SECONDS\n}\n\n/**\n * Resolve the refresh grace window (seconds) for `/auth/refresh`. Precedence:\n * `JWT_REFRESH_GRACE_SECONDS` env var → `settings.security.jwtRefreshGraceSeconds`\n * DB value → 7-day default.\n */\nexport async function getJwtRefreshGraceSecondsFromDb(\n db: { prepare: (query: string) => any } | null | undefined,\n env?: Record<string, any> | null\n): Promise<number> {\n const DEFAULT_GRACE = 60 * 60 * 24 * 7\n const envParsed = parseDuration(env?.JWT_REFRESH_GRACE_SECONDS)\n if (envParsed) return envParsed\n\n if (db) {\n try {\n const row = await db\n .prepare(\"SELECT data FROM documents WHERE type_id = 'site_settings' AND slug = 'security' AND tenant_id = 'default' AND is_current_draft = 1 AND deleted_at IS NULL\")\n .first() as { data: string } | null\n if (row?.data) {\n const data = JSON.parse(row.data)\n const parsed = parseDuration(data.jwtRefreshGraceSeconds?.toString())\n if (parsed) return parsed\n }\n } catch (err) {\n console.warn('Failed to read jwtRefreshGraceSeconds from settings:', err)\n }\n }\n return DEFAULT_GRACE\n}\n\n/**\n * Decode a JWT payload without verifying the signature. Returns null on any\n * parsing failure. Callers MUST independently verify the signature before\n * trusting this value — used from the grace-window refresh path where the\n * signature is verified explicitly via `verifyHs256Signature`.\n */\nfunction decodeJwtPayload(token: string): JWTPayload | null {\n try {\n const parts = token.split('.')\n if (parts.length !== 3) return null\n const b64 = parts[1]!.replace(/-/g, '+').replace(/_/g, '/')\n const padded = b64 + '='.repeat((4 - (b64.length % 4)) % 4)\n const json = atob(padded)\n const obj = JSON.parse(json)\n if (!obj || typeof obj.exp !== 'number') return null\n return obj as JWTPayload\n } catch {\n return null\n }\n}\n\nfunction base64UrlToBytes(b64url: string): Uint8Array {\n const b64 = b64url.replace(/-/g, '+').replace(/_/g, '/')\n const padded = b64 + '='.repeat((4 - (b64.length % 4)) % 4)\n const bin = atob(padded)\n const bytes = new Uint8Array(bin.length)\n for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i)\n return bytes\n}\n\n/**\n * Verify a JWT's HS256 signature using Web Crypto, independent of hono/jwt.\n * Returns true iff the signature matches the header.payload portion.\n */\nasync function verifyHs256Signature(token: string, secret: string): Promise<boolean> {\n try {\n const parts = token.split('.')\n if (parts.length !== 3) return false\n const encoder = new TextEncoder()\n const key = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['verify']\n )\n const signature = base64UrlToBytes(parts[2]!)\n const message = encoder.encode(`${parts[0]}.${parts[1]}`)\n return await crypto.subtle.verify('HMAC', key, signature, message)\n } catch {\n return false\n }\n}\n\nexport class AuthManager {\n static async generateToken(\n userId: string,\n email: string,\n role: string,\n secret?: string,\n expiresInSeconds?: number\n ): Promise<string> {\n const ttl = expiresInSeconds && expiresInSeconds > 0\n ? Math.floor(expiresInSeconds)\n : DEFAULT_JWT_EXPIRES_IN_SECONDS\n const now = Math.floor(Date.now() / 1000)\n const payload: JWTPayload = {\n userId,\n email,\n role,\n exp: now + ttl,\n iat: now\n }\n\n return await sign(payload, secret || JWT_SECRET_FALLBACK, 'HS256')\n }\n\n /**\n * Verify a token's signature and expiration.\n *\n * IMPORTANT: pass the `JWT_SECRET` binding (e.g. `c.env.JWT_SECRET`) as the\n * `secret` argument. If omitted, this falls back to a development-only\n * placeholder secret — tokens signed with the real `JWT_SECRET` will then\n * silently fail verification. From inside a Hono handler prefer\n * `AuthManager.verifyAuthRequest(c)`, which handles header/cookie extraction\n * and pulls the secret from `c.env` for you.\n *\n * If `graceSeconds` > 0, tokens whose `exp` is within the grace window\n * (i.e. expired by no more than `graceSeconds`) are still returned. This\n * supports a sliding-session refresh endpoint that accepts recently-expired\n * tokens. Signature failures always return null.\n */\n static async verifyToken(\n token: string,\n secret?: string,\n graceSeconds: number = 0\n ): Promise<JWTPayload | null> {\n const effectiveSecret = secret || JWT_SECRET_FALLBACK\n try {\n let payload: JWTPayload | null = null\n try {\n payload = await verify(token, effectiveSecret, 'HS256') as JWTPayload\n } catch (verifyError: any) {\n // hono/jwt checks `exp` before signature, so a bad-signature token\n // that happens to be expired will throw JwtTokenExpired here. For\n // the grace window, we still require a valid HS256 signature before\n // accepting the payload.\n const name = verifyError?.name || ''\n const message = String(verifyError?.message || '')\n const isExpired = name === 'JwtTokenExpired' || message.includes('expired')\n if (!isExpired || graceSeconds <= 0) {\n throw verifyError\n }\n const signatureValid = await verifyHs256Signature(token, effectiveSecret)\n if (!signatureValid) return null\n const decoded = decodeJwtPayload(token)\n if (!decoded) return null\n payload = decoded\n }\n\n if (!payload) return null\n\n const now = Math.floor(Date.now() / 1000)\n if (payload.exp < now - Math.max(0, Math.floor(graceSeconds))) {\n return null\n }\n\n return payload\n } catch (error) {\n console.error('Token verification failed:', error)\n return null\n }\n }\n\n /**\n * Verify the JWT on an incoming Hono request using the `JWT_SECRET`\n * binding from `c.env`. Reads the token from the `Authorization: Bearer …`\n * header first, then falls back to the `auth_token` cookie. Returns the\n * decoded payload, or null when the token is missing, malformed, expired,\n * or signed with a different secret.\n *\n * Use this from custom Hono routes mounted alongside SonicJS — it\n * resolves the secret the same way `requireAuth()` does, without forcing\n * the caller to plumb it through manually.\n */\n static async verifyAuthRequest(c: Context): Promise<JWTPayload | null> {\n let token = c.req.header('Authorization')?.replace('Bearer ', '')\n if (!token) {\n token = getCookie(c, 'auth_token')\n }\n if (!token) return null\n const secret = (c.env as any)?.JWT_SECRET\n return await AuthManager.verifyToken(token, secret)\n }\n\n static async hashPassword(password: string): Promise<string> {\n const iterations = 100000\n const salt = new Uint8Array(16)\n crypto.getRandomValues(salt)\n\n const encoder = new TextEncoder()\n const keyMaterial = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(password),\n 'PBKDF2',\n false,\n ['deriveBits']\n )\n\n const hashBuffer = await crypto.subtle.deriveBits(\n {\n name: 'PBKDF2',\n salt,\n iterations,\n hash: 'SHA-256'\n },\n keyMaterial,\n 256\n )\n\n const saltHex = Array.from(salt).map(b => b.toString(16).padStart(2, '0')).join('')\n const hashHex = Array.from(new Uint8Array(hashBuffer)).map(b => b.toString(16).padStart(2, '0')).join('')\n\n return `pbkdf2:${iterations}:${saltHex}:${hashHex}`\n }\n\n static async hashPasswordLegacy(password: string): Promise<string> {\n const encoder = new TextEncoder()\n const data = encoder.encode(password + 'salt-change-in-production')\n const hashBuffer = await crypto.subtle.digest('SHA-256', data)\n const hashArray = Array.from(new Uint8Array(hashBuffer))\n return hashArray.map(b => b.toString(16).padStart(2, '0')).join('')\n }\n\n static async verifyPassword(password: string, storedHash: string): Promise<boolean> {\n if (storedHash.startsWith('pbkdf2:')) {\n // PBKDF2 format: pbkdf2:<iterations>:<salt_hex>:<hash_hex>\n const parts = storedHash.split(':')\n if (parts.length !== 4) return false\n\n const iterationsStr = parts[1]!\n const saltHex = parts[2]!\n const expectedHashHex = parts[3]!\n const iterations = parseInt(iterationsStr, 10)\n\n const saltBytes = saltHex.match(/.{2}/g)\n if (!saltBytes) return false\n const salt = new Uint8Array(saltBytes.map(byte => parseInt(byte, 16)))\n\n const encoder = new TextEncoder()\n const keyMaterial = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(password),\n 'PBKDF2',\n false,\n ['deriveBits']\n )\n\n const hashBuffer = await crypto.subtle.deriveBits(\n {\n name: 'PBKDF2',\n salt,\n iterations,\n hash: 'SHA-256'\n },\n keyMaterial,\n 256\n )\n\n const actualHashHex = Array.from(new Uint8Array(hashBuffer)).map(b => b.toString(16).padStart(2, '0')).join('')\n\n // Constant-time comparison\n if (actualHashHex.length !== expectedHashHex.length) return false\n let result = 0\n for (let i = 0; i < actualHashHex.length; i++) {\n result |= actualHashHex.charCodeAt(i) ^ expectedHashHex.charCodeAt(i)\n }\n return result === 0\n }\n\n // Legacy SHA-256 format (no colons in hash)\n const legacyHash = await this.hashPasswordLegacy(password)\n // Constant-time comparison for legacy too\n if (legacyHash.length !== storedHash.length) return false\n let result = 0\n for (let i = 0; i < legacyHash.length; i++) {\n result |= legacyHash.charCodeAt(i) ^ storedHash.charCodeAt(i)\n }\n return result === 0\n }\n\n static isLegacyHash(storedHash: string): boolean {\n return !storedHash.startsWith('pbkdf2:')\n }\n\n /**\n * Set authentication cookie - useful for plugins implementing alternative auth methods\n * @param c - Hono context\n * @param token - JWT token to set in cookie\n * @param options - Optional cookie configuration\n */\n static setAuthCookie(c: Context, token: string, options?: {\n maxAge?: number\n secure?: boolean\n httpOnly?: boolean\n sameSite?: 'Strict' | 'Lax' | 'None'\n }): void {\n setCookie(c, 'auth_token', token, {\n httpOnly: options?.httpOnly ?? true,\n secure: options?.secure ?? true,\n sameSite: options?.sameSite ?? 'Strict',\n maxAge: options?.maxAge ?? getJwtExpirySeconds((c as any)?.env)\n })\n }\n}\n\n// Middleware to require authentication.\n// The Better Auth session middleware (app.ts) has already populated c.get('user')\n// from the session cookie; here we just enforce its presence.\nexport const requireAuth = () => {\n return async (c: Context, next: Next) => {\n const user = c.get('user') as JWTPayload | undefined\n\n if (!user) {\n const acceptHeader = c.req.header('Accept') || ''\n if (acceptHeader.includes('text/html')) {\n return c.redirect('/auth/login?error=Please login to access the admin area')\n }\n return c.json({ error: 'Authentication required' }, 401)\n }\n\n return await next()\n }\n}\n\n// Middleware to require specific role. Must run after requireAuth / the session\n// middleware so c.get('user') is set.\nexport const requireRole = (requiredRole: string | string[]) => {\n return async (c: Context, next: Next) => {\n const user = c.get('user') as JWTPayload | undefined\n\n if (!user) {\n const acceptHeader = c.req.header('Accept') || ''\n if (acceptHeader.includes('text/html')) {\n return c.redirect('/auth/login?error=Please login to access the admin area')\n }\n return c.json({ error: 'Authentication required' }, 401)\n }\n\n const roles = Array.isArray(requiredRole) ? requiredRole : [requiredRole]\n\n if (!roles.includes(user.role)) {\n const acceptHeader = c.req.header('Accept') || ''\n if (acceptHeader.includes('text/html')) {\n return c.redirect('/auth/login?error=You do not have permission to access this area')\n }\n return c.json({ error: 'Insufficient permissions' }, 403)\n }\n\n return await next()\n }\n}\n\n// Middleware to require a live RBAC grant for the signed-in user. This is the\n// dynamic replacement for legacy `users.role` checks on admin routes.\nexport const requireRbac = (resource: string, verb: string) => {\n return async (c: Context, next: Next) => {\n const user = c.get('user') as JWTPayload | undefined\n\n if (!user) {\n const acceptHeader = c.req.header('Accept') || ''\n if (acceptHeader.includes('text/html')) {\n return c.redirect('/auth/login?error=Please login to access the admin area')\n }\n return c.json({ error: 'Authentication required' }, 401)\n }\n\n // Fast path: use pre-computed perms from the /admin/* middleware (avoids DB hit).\n const cachedPerms = (c as any).get('rbacPerms') as string[] | undefined\n let allowed: boolean\n if (cachedPerms !== undefined) {\n allowed = cachedPerms.includes(`${resource}:${verb}`)\n } else {\n allowed = await new RbacService((c.env as any).DB).can(user.userId, resource, verb)\n }\n\n if (!allowed) {\n const acceptHeader = c.req.header('Accept') || ''\n if (acceptHeader.includes('text/html')) {\n return c.redirect('/auth/login?error=You do not have permission to access this area')\n }\n return c.json({ error: 'Insufficient permissions' }, 403)\n }\n\n return await next()\n }\n}\n\n// Optional auth middleware. The session middleware already sets c.get('user')\n// when a valid session exists, so this is a no-op kept for API compatibility.\nexport const optionalAuth = () => {\n return async (_c: Context, next: Next) => {\n return await next()\n }\n}\n","import { MiddlewareHandler } from 'hono'\nimport { metricsTracker } from '../utils/metrics'\n\n/**\n * Middleware to track all HTTP requests for real-time analytics\n * Excludes the metrics endpoint itself to avoid inflating the count\n */\nexport const metricsMiddleware = (): MiddlewareHandler => {\n return async (c, next) => {\n const path = new URL(c.req.url).pathname\n\n // Don't track the metrics endpoint itself to avoid self-inflating counts\n if (path !== '/admin/dashboard/api/metrics') {\n metricsTracker.recordRequest()\n }\n\n // Continue with the request\n await next()\n }\n}\n","/**\n * CSRF Protection Middleware — Signed Double-Submit Cookie\n *\n * Stateless CSRF protection for Cloudflare Workers (no session store needed).\n * Token format: `<nonce>.<hmac>` where HMAC-SHA256 is keyed with JWT_SECRET.\n *\n * Flow:\n * GET — ensureCsrfCookie(): reuse existing valid cookie or set a new one\n * POST/PUT/DELETE/PATCH — validate X-CSRF-Token header === csrf_token cookie, HMAC valid\n *\n * Exempt:\n * - Safe methods (GET, HEAD, OPTIONS)\n * - Auth routes that create sessions (/auth/login*, /auth/register*, etc.)\n * - Public form submissions (/forms/*, /api/forms/*) — NOT /admin/forms/*\n * - Requests with no auth_token cookie (Bearer-only or API-key-only)\n */\n\nimport type { Context, Next } from 'hono'\nimport { getCookie, setCookie } from 'hono/cookie'\n\n// Fallback secret — mirrors auth.ts behavior for local dev without wrangler secret\nconst JWT_SECRET_FALLBACK = 'your-super-secret-jwt-key-change-in-production'\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/** Convert ArrayBuffer to URL-safe base64 (no padding). */\nexport function arrayBufferToBase64Url(buffer: ArrayBuffer): string {\n const bytes = new Uint8Array(buffer)\n let binary = ''\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]!)\n }\n return btoa(binary).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '')\n}\n\n/** Import a string key for HMAC-SHA256. */\nasync function getHmacKey(secret: string): Promise<CryptoKey> {\n const encoder = new TextEncoder()\n return crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign', 'verify']\n )\n}\n\n// ============================================================================\n// Token Generation & Validation\n// ============================================================================\n\n/**\n * Generate a signed CSRF token: `<nonce>.<hmac_signature>`\n * - nonce = 32 random bytes, base64url-encoded\n * - signature = HMAC-SHA256(nonce, secret), base64url-encoded\n */\nexport async function generateCsrfToken(secret: string): Promise<string> {\n const nonceBytes = new Uint8Array(32)\n crypto.getRandomValues(nonceBytes)\n const nonce = arrayBufferToBase64Url(nonceBytes.buffer)\n\n const key = await getHmacKey(secret)\n const encoder = new TextEncoder()\n const signatureBuffer = await crypto.subtle.sign('HMAC', key, encoder.encode(nonce))\n const signature = arrayBufferToBase64Url(signatureBuffer)\n\n return `${nonce}.${signature}`\n}\n\n/**\n * Validate a signed CSRF token.\n *\n * Checks that the token has the correct `<nonce>.<signature>` format and that\n * the HMAC signature is valid for the given secret. Uses crypto.subtle.verify\n * which provides constant-time comparison.\n *\n * NOTE: No expiry check here — by design. The security property of signed\n * double-submit comes from the unpredictability of the nonce + the\n * secret-bound HMAC, not from time-bounding. The cookie's maxAge (86400s)\n * handles expiry at the browser level.\n */\nexport async function validateCsrfToken(token: string, secret: string): Promise<boolean> {\n if (!token || typeof token !== 'string') return false\n\n const dotIndex = token.indexOf('.')\n if (dotIndex === -1) return false\n\n const nonce = token.substring(0, dotIndex)\n const signature = token.substring(dotIndex + 1)\n\n if (!nonce || !signature) return false\n\n try {\n const key = await getHmacKey(secret)\n const encoder = new TextEncoder()\n\n // Decode the signature from base64url\n const sigPadded = signature.replace(/-/g, '+').replace(/_/g, '/')\n const sigBinary = atob(sigPadded)\n const sigBytes = new Uint8Array(sigBinary.length)\n for (let i = 0; i < sigBinary.length; i++) {\n sigBytes[i] = sigBinary.charCodeAt(i)\n }\n\n // crypto.subtle.verify is constant-time\n return await crypto.subtle.verify('HMAC', key, sigBytes.buffer, encoder.encode(nonce))\n } catch {\n return false\n }\n}\n\n// ============================================================================\n// Default Exempt Paths\n// ============================================================================\n\nconst DEFAULT_EXEMPT_PATHS = [\n '/auth/login',\n '/auth/register',\n '/auth/seed-admin',\n '/test-seed-defaults',\n '/test-cleanup',\n '/auth/accept-invitation',\n '/auth/reset-password',\n '/auth/request-password-reset',\n '/auth/otp',\n '/auth/magic-link',\n '/auth/sign-out',\n '/auth/sign-in',\n '/auth/sign-up',\n '/auth/get-session',\n '/auth/verify',\n '/api/stripe/webhook',\n '/api/events',\n]\n\n/**\n * Check whether a request path is exempt from CSRF validation.\n * - Exact match or startsWith for auth routes (e.g. /auth/login/form)\n * - /forms/* and /api/forms/* are exempt (public submissions)\n * - /api/search* is exempt (read-only POST for complex query params)\n * - /admin/forms/* is NOT exempt\n */\nfunction isExemptPath(path: string, extraExemptPaths: string[] = []): boolean {\n // Public form routes — NOT /admin/forms/*\n if (path.startsWith('/forms/') || path.startsWith('/api/forms/') || path === '/forms' || path === '/api/forms') {\n return true\n }\n\n // Search API — read-only POST (includes /api/search/click, /api/search/facet-click)\n if (path.startsWith('/api/search')) {\n return true\n }\n\n const allExempt = [...DEFAULT_EXEMPT_PATHS, ...extraExemptPaths]\n for (const exempt of allExempt) {\n if (path === exempt || path.startsWith(exempt + '/')) {\n return true\n }\n }\n\n return false\n}\n\n// ============================================================================\n// Middleware\n// ============================================================================\n\nexport interface CsrfOptions {\n /** Additional paths to exempt from CSRF validation. */\n exemptPaths?: string[]\n}\n\n/**\n * CSRF protection middleware (Signed Double-Submit Cookie).\n *\n * - GET/HEAD/OPTIONS: ensure a valid csrf_token cookie exists\n * - POST/PUT/DELETE/PATCH: validate X-CSRF-Token header matches cookie, HMAC valid\n * - Exempt: auth routes, public /forms/*, Bearer-only, API-key-only\n */\nexport function csrfProtection(options: CsrfOptions = {}) {\n return async (c: Context, next: Next): Promise<Response | void> => {\n const method = c.req.method.toUpperCase()\n const path = new URL(c.req.url).pathname\n const secret = c.env?.JWT_SECRET || JWT_SECRET_FALLBACK\n\n // Warn if using fallback secret in production\n if (c.env?.ENVIRONMENT === 'production' && !c.env?.JWT_SECRET) {\n console.warn(\n '[CSRF] WARNING: JWT_SECRET is not set in production. ' +\n 'CSRF tokens are signed with the fallback key, which is insecure.'\n )\n }\n\n // Safe methods — just ensure cookie, then pass through\n if (method === 'GET' || method === 'HEAD' || method === 'OPTIONS') {\n await ensureCsrfCookie(c, secret)\n await next()\n return\n }\n\n // Exempt paths — pass through without validation\n if (isExemptPath(path, options.exemptPaths)) {\n await next()\n return\n }\n\n // Bearer-only or API-key-only requests (no auth_token cookie) — exempt\n const authCookie = getCookie(c, 'auth_token')\n if (!authCookie) {\n await next()\n return\n }\n\n // Requests with an Authorization header use token-based auth — the cookie\n // is incidental and CSRF protection is unnecessary (the attacker cannot\n // forge the Authorization header from a cross-origin page).\n const authHeader = c.req.header('Authorization')\n if (authHeader) {\n await next()\n return\n }\n\n // State-changing request with cookie auth — validate CSRF\n const cookieToken = getCookie(c, 'csrf_token')\n let headerToken = c.req.header('X-CSRF-Token')\n\n // Fallback: check _csrf field in form-encoded body (regular HTML form submissions)\n if (!headerToken) {\n const contentType = c.req.header('Content-Type') || ''\n if (contentType.includes('application/x-www-form-urlencoded') || contentType.includes('multipart/form-data')) {\n try {\n const body = await c.req.parseBody()\n headerToken = body['_csrf'] as string | undefined\n } catch {\n // Body not parseable — leave headerToken undefined\n }\n }\n }\n\n if (!cookieToken || !headerToken) {\n return csrfError(c, 'CSRF token missing')\n }\n\n if (cookieToken !== headerToken) {\n return csrfError(c, 'CSRF token mismatch')\n }\n\n const isValid = await validateCsrfToken(cookieToken, secret)\n if (!isValid) {\n return csrfError(c, 'CSRF token invalid')\n }\n\n await next()\n }\n}\n\n/**\n * Ensure a valid CSRF cookie exists. Check-then-reuse: if the existing cookie\n * has a valid HMAC signature, reuse it (no new Set-Cookie header). Only\n * generate a fresh token when the cookie is missing or has an invalid signature.\n */\nasync function ensureCsrfCookie(c: Context, secret: string): Promise<void> {\n const existing = getCookie(c, 'csrf_token')\n\n if (existing) {\n const isValid = await validateCsrfToken(existing, secret)\n if (isValid) {\n // Reuse existing valid token — no Set-Cookie needed\n c.set('csrfToken', existing)\n return\n }\n }\n\n // Generate fresh token\n const token = await generateCsrfToken(secret)\n c.set('csrfToken', token)\n\n const isDev = c.env?.ENVIRONMENT === 'development' || !c.env?.ENVIRONMENT\n setCookie(c, 'csrf_token', token, {\n httpOnly: false, // JS must read this cookie\n secure: !isDev,\n sameSite: 'Strict',\n path: '/',\n maxAge: 86400, // 24 hours — browser-side expiry\n })\n}\n\n/** Return a 403 CSRF error — HTML for browser requests, JSON for API. */\nfunction csrfError(c: Context, message: string): Response {\n const accept = c.req.header('Accept') || ''\n if (accept.includes('text/html')) {\n return c.html(\n `<!DOCTYPE html><html><head><title>403 Forbidden</title></head>` +\n `<body><h1>403 Forbidden</h1><p>${message}</p></body></html>`,\n 403\n )\n }\n return c.json({ error: message, status: 403 }, 403)\n}\n","import { Context, Next } from 'hono'\n\ninterface RateLimitOptions {\n max: number\n windowMs: number\n keyPrefix: string\n}\n\ninterface RateLimitEntry {\n count: number\n resetAt: number\n}\n\n/**\n * KV-based sliding window rate limiter middleware.\n * Gracefully skips if CACHE_KV binding is not available.\n */\nexport function rateLimit(options: RateLimitOptions) {\n const { max, windowMs, keyPrefix } = options\n\n return async (c: Context, next: Next) => {\n const kv = (c.env as any)?.CACHE_KV\n if (!kv) {\n // No KV binding available — skip rate limiting\n return await next()\n }\n\n const ip = c.req.header('cf-connecting-ip') || c.req.header('x-forwarded-for') || 'unknown'\n const key = `ratelimit:${keyPrefix}:${ip}`\n\n try {\n const now = Date.now()\n const stored = await kv.get(key, 'json') as RateLimitEntry | null\n\n let entry: RateLimitEntry\n if (stored && stored.resetAt > now) {\n entry = stored\n } else {\n entry = { count: 0, resetAt: now + windowMs }\n }\n\n entry.count++\n\n // Calculate TTL in seconds (KV expiration)\n const ttlSeconds = Math.ceil((entry.resetAt - now) / 1000)\n\n if (entry.count > max) {\n // Store the updated count even when rejecting\n await kv.put(key, JSON.stringify(entry), { expirationTtl: Math.max(ttlSeconds, 60) })\n\n const retryAfter = Math.ceil((entry.resetAt - now) / 1000)\n c.header('Retry-After', String(retryAfter))\n c.header('X-RateLimit-Limit', String(max))\n c.header('X-RateLimit-Remaining', '0')\n c.header('X-RateLimit-Reset', String(Math.ceil(entry.resetAt / 1000)))\n return c.json({ error: 'Too many requests. Please try again later.' }, 429)\n }\n\n await kv.put(key, JSON.stringify(entry), { expirationTtl: Math.max(ttlSeconds, 60) })\n\n c.header('X-RateLimit-Limit', String(max))\n c.header('X-RateLimit-Remaining', String(max - entry.count))\n c.header('X-RateLimit-Reset', String(Math.ceil(entry.resetAt / 1000)))\n\n return await next()\n } catch (error) {\n // Rate limiting should never break the app\n console.error('Rate limiter error (non-fatal):', error)\n return await next()\n }\n }\n}\n","import { Context, Next } from 'hono'\n\n/**\n * Security headers middleware.\n * Sets standard security headers on every response.\n * Skips HSTS in development to avoid local dev issues.\n */\nexport const securityHeadersMiddleware = () => {\n return async (c: Context, next: Next) => {\n await next()\n\n c.header('X-Content-Type-Options', 'nosniff')\n c.header('X-Frame-Options', 'SAMEORIGIN')\n c.header('Referrer-Policy', 'strict-origin-when-cross-origin')\n c.header('Permissions-Policy', 'camera=(), microphone=(), geolocation=()')\n\n // Only set HSTS in non-development environments\n const environment = (c.env as any)?.ENVIRONMENT\n if (environment !== 'development') {\n c.header('Strict-Transport-Security', 'max-age=31536000; includeSubDomains')\n }\n }\n}\n","/**\n * Plugin Middleware\n *\n * Provides middleware functions for checking plugin status and enforcing plugin requirements\n */\n\nimport type { D1Database } from '@cloudflare/workers-types'\n\n/**\n * Check if a plugin is active\n * @param db - The D1 database instance\n * @param pluginId - The plugin ID to check\n * @returns Promise<boolean> - True if the plugin is active, false otherwise\n */\nexport async function isPluginActive(db: D1Database, pluginId: string): Promise<boolean> {\n try {\n // documents table is the authoritative source — PluginService writes here on install/activate.\n // Sidebar nav uses the same query pattern; plugins table is unreliable (may not exist).\n const docResult = await db\n .prepare(\n `SELECT json_extract(data, '$.status') as status FROM documents\n WHERE slug = ? AND type_id = 'plugin' AND tenant_id = 'default'\n AND is_current_draft = 1 AND deleted_at IS NULL`\n )\n .bind(pluginId)\n .first()\n return (docResult as any)?.status === 'active'\n } catch (error) {\n console.error(`[isPluginActive] Error checking plugin status for ${pluginId}:`, error)\n return false\n }\n}\n\n/**\n * Middleware to require a plugin to be active\n * Throws an error if the plugin is not active\n * @param db - The D1 database instance\n * @param pluginId - The plugin ID to check\n * @throws Error if plugin is not active\n */\nexport async function requireActivePlugin(db: D1Database, pluginId: string): Promise<void> {\n const isActive = await isPluginActive(db, pluginId)\n if (!isActive) {\n throw new Error(`Plugin '${pluginId}' is required but is not active`)\n }\n}\n\n/**\n * Middleware to require multiple plugins to be active\n * Throws an error if any plugin is not active\n * @param db - The D1 database instance\n * @param pluginIds - Array of plugin IDs to check\n * @throws Error if any plugin is not active\n */\nexport async function requireActivePlugins(db: D1Database, pluginIds: string[]): Promise<void> {\n for (const pluginId of pluginIds) {\n await requireActivePlugin(db, pluginId)\n }\n}\n\n/**\n * Get all active plugins\n * @param db - The D1 database instance\n * @returns Promise<any[]> - Array of active plugin records\n */\nexport async function getActivePlugins(db: D1Database): Promise<any[]> {\n try {\n const { results } = await db\n .prepare(\n `SELECT slug as id, json_extract(data, '$.status') as status, data FROM documents\n WHERE type_id = 'plugin' AND tenant_id = 'default'\n AND q_plugin_status = 'active' AND is_current_draft = 1 AND deleted_at IS NULL`\n )\n .all()\n\n return results || []\n } catch (error) {\n console.error('[getActivePlugins] Error fetching active plugins:', error)\n return []\n }\n}\n","/**\n * Middleware Module Exports\n *\n * Request processing middleware for SonicJS\n *\n * Note: Most middleware is currently in the monolith and will be migrated later.\n * For now, we only export the bootstrap middleware which is used for system initialization.\n */\n\n// Bootstrap middleware\nexport { bootstrapMiddleware, verifySecurityConfig } from './bootstrap'\n\n// Auth middleware\nexport {\n AuthManager,\n requireAuth,\n requireRole,\n optionalAuth,\n getJwtExpirySeconds,\n getJwtExpirySecondsFromDb,\n getJwtRefreshGraceSecondsFromDb,\n} from './auth'\n\n// Metrics middleware\nexport { metricsMiddleware } from './metrics'\n\n// CSRF protection middleware\nexport { csrfProtection, generateCsrfToken, validateCsrfToken } from './csrf'\n\n// Rate limiting middleware\nexport { rateLimit } from './rate-limit'\n\n// Re-export types and functions that are referenced but implemented in monolith\n// These are placeholder exports to maintain API compatibility\nexport type Permission = string\nexport type UserPermissions = {\n userId: string\n permissions: Permission[]\n}\n\n// Middleware stubs - these return pass-through middleware that call next()\nexport const loggingMiddleware: any = () => async (_c: any, next: any) => await next()\nexport const detailedLoggingMiddleware: any = () => async (_c: any, next: any) => await next()\nexport const securityLoggingMiddleware: any = () => async (_c: any, next: any) => await next()\nexport const performanceLoggingMiddleware: any = () => async (_c: any, next: any) => await next()\nexport const cacheHeaders: any = () => async (_c: any, next: any) => await next()\nexport const compressionMiddleware: any = async (_c: any, next: any) => await next()\nexport { securityHeadersMiddleware as securityHeaders } from './security-headers'\n\n// Other stubs\nexport const PermissionManager: any = {}\nexport const requirePermission: any = () => async (_c: any, next: any) => await next()\nexport const requireAnyPermission: any = () => async (_c: any, next: any) => await next()\nexport const logActivity: any = () => {}\nexport { requireActivePlugin, requireActivePlugins, getActivePlugins, isPluginActive } from './plugin-middleware'\n"]}