'use strict';

var zod = require('zod');

// src/plugins/plugin-manifest.ts
var PluginManifestSchema = zod.z.object({
  // Basic information
  id: zod.z.string().min(1).regex(/^[a-z0-9-]+$/),
  name: zod.z.string().min(1),
  version: zod.z.string().regex(/^\d+\.\d+\.\d+/),
  description: zod.z.string().optional(),
  // Author information
  author: zod.z.object({
    name: zod.z.string(),
    email: zod.z.string().email().optional(),
    url: zod.z.string().url().optional()
  }).optional(),
  // Plugin metadata
  license: zod.z.string().optional(),
  homepage: zod.z.string().url().optional(),
  repository: zod.z.string().optional(),
  // Dependencies and compatibility
  dependencies: zod.z.record(zod.z.string(), zod.z.string()).optional(),
  cfCmsVersion: zod.z.string().optional(),
  // Capabilities
  capabilities: zod.z.object({
    routes: zod.z.boolean().optional(),
    hooks: zod.z.boolean().optional(),
    adminPages: zod.z.boolean().optional(),
    middleware: zod.z.boolean().optional(),
    models: zod.z.boolean().optional(),
    services: zod.z.boolean().optional(),
    themes: zod.z.boolean().optional(),
    fieldTypes: zod.z.boolean().optional()
  }).optional(),
  // Configuration
  config: zod.z.object({
    schema: zod.z.record(zod.z.string(), zod.z.any()).optional(),
    defaults: zod.z.record(zod.z.string(), zod.z.any()).optional()
  }).optional(),
  // Database requirements
  database: zod.z.object({
    tables: zod.z.array(zod.z.string()).optional(),
    migrations: zod.z.array(zod.z.string()).optional()
  }).optional(),
  // Asset requirements
  assets: zod.z.object({
    styles: zod.z.array(zod.z.string()).optional(),
    scripts: zod.z.array(zod.z.string()).optional()
  }).optional(),
  // Plugin flags
  isCore: zod.z.boolean().optional(),
  isActive: zod.z.boolean().optional(),
  isPublic: zod.z.boolean().optional()
});
function validateManifest(manifest) {
  try {
    PluginManifestSchema.parse(manifest);
    return { valid: true, errors: [] };
  } catch (error) {
    if (error instanceof zod.z.ZodError) {
      return {
        valid: false,
        errors: error.issues.map((e) => `${e.path.join(".")}: ${e.message}`)
      };
    }
    return { valid: false, errors: ["Unknown validation error"] };
  }
}
function validateDependencies(manifest, installedPlugins) {
  const errors = [];
  if (!manifest.dependencies) {
    return { valid: true, errors: [] };
  }
  for (const [depId, depVersion] of Object.entries(manifest.dependencies)) {
    const installed = installedPlugins.get(depId);
    if (!installed) {
      errors.push(`Missing dependency: ${depId}@${depVersion}`);
      continue;
    }
    if (!isVersionCompatible(installed.version, depVersion)) {
      errors.push(`Incompatible version for ${depId}: required ${depVersion}, found ${installed.version}`);
    }
  }
  return { valid: errors.length === 0, errors };
}
function isVersionCompatible(installed, required) {
  const [installedMajor] = installed.split(".");
  if (required.startsWith("^")) {
    const cleanRequired = required.replace("^", "");
    return installedMajor === cleanRequired.split(".")[0];
  }
  if (required.startsWith("~")) {
    const [reqMajor, reqMinor] = required.replace("~", "").split(".");
    const [instMajor, instMinor] = installed.split(".");
    return instMajor === reqMajor && instMinor === reqMinor;
  }
  return installed === required;
}
function resolvePluginLoadOrder(plugins) {
  const errors = [];
  const order = [];
  const visited = /* @__PURE__ */ new Set();
  const visiting = /* @__PURE__ */ new Set();
  function visit(id) {
    if (visited.has(id)) return true;
    if (visiting.has(id)) {
      errors.push(`Circular dependency detected: ${id}`);
      return false;
    }
    visiting.add(id);
    const plugin = plugins.get(id);
    if (!plugin) {
      errors.push(`Plugin not found: ${id}`);
      return false;
    }
    if (plugin.dependencies) {
      for (const depId of Object.keys(plugin.dependencies)) {
        if (!visit(depId)) return false;
      }
    }
    visiting.delete(id);
    visited.add(id);
    order.push(id);
    return true;
  }
  for (const id of plugins.keys()) {
    if (!visited.has(id)) {
      visit(id);
    }
  }
  return { order, errors };
}

// src/plugins/plugin-registry.ts
var PluginRegistry = class {
  db;
  plugins = /* @__PURE__ */ new Map();
  statuses = /* @__PURE__ */ new Map();
  constructor(options) {
    this.db = options.db;
  }
  /**
   * Initialize registry - load plugins from database
   */
  async initialize() {
    try {
      const result = await this.db.prepare("SELECT * FROM plugins WHERE status != ?").bind("deleted").all();
      if (result.results) {
        for (const row of result.results) {
          const manifest = {
            id: row.id,
            name: row.name,
            version: row.version,
            description: row.description,
            author: {
              name: row.author
            }
          };
          const resolved = {
            ...manifest,
            path: "",
            // Will be set when plugin is loaded
            entry: "",
            // Will be set when plugin is loaded
            manifestPath: "",
            // Will be set when plugin is loaded
            installedAt: row.installed_at,
            updatedAt: row.last_updated,
            status: row.status,
            error: row.error_message
          };
          this.plugins.set(manifest.id, resolved);
          this.updateStatus(manifest.id, resolved);
        }
      }
    } catch (error) {
      console.error("[PluginRegistry] Failed to initialize:", error);
      throw error;
    }
  }
  /**
   * Register a plugin
   */
  async register(manifest, path, entry) {
    const now = Math.floor(Date.now() / 1e3);
    const resolved = {
      ...manifest,
      path,
      entry,
      manifestPath: `${path}/manifest.json`,
      installedAt: now,
      updatedAt: now,
      status: "inactive"
    };
    this.plugins.set(manifest.id, resolved);
    this.updateStatus(manifest.id, resolved);
    await this.db.prepare(`
        INSERT OR REPLACE INTO plugins 
        (id, name, display_name, description, version, author, category, status, installed_at, last_updated)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
      `).bind(
      manifest.id,
      manifest.name,
      manifest.name,
      // display_name
      manifest.description || "",
      manifest.version,
      manifest.author?.name || "Unknown",
      "custom",
      // category
      "inactive",
      now,
      now
    ).run();
  }
  /**
   * Unregister a plugin
   */
  async unregister(id) {
    this.plugins.delete(id);
    this.statuses.delete(id);
    await this.db.prepare("UPDATE plugins SET status = ? WHERE id = ?").bind("deleted", id).run();
  }
  /**
   * Get plugin by ID
   */
  get(id) {
    return this.plugins.get(id);
  }
  /**
   * Get all registered plugins
   */
  getAll() {
    return Array.from(this.plugins.values());
  }
  /**
   * Get active plugins
   */
  getActive() {
    return Array.from(this.plugins.values()).filter((p) => p.status === "active");
  }
  /**
   * Check if plugin is registered
   */
  has(id) {
    return this.plugins.has(id);
  }
  /**
   * Activate a plugin
   */
  async activate(id) {
    const plugin = this.plugins.get(id);
    if (!plugin) throw new Error(`Plugin not found: ${id}`);
    plugin.status = "active";
    this.updateStatus(id, plugin);
    await this.db.prepare("UPDATE plugins SET status = ? WHERE id = ?").bind("active", id).run();
  }
  /**
   * Deactivate a plugin
   */
  async deactivate(id) {
    const plugin = this.plugins.get(id);
    if (!plugin) throw new Error(`Plugin not found: ${id}`);
    plugin.status = "inactive";
    this.updateStatus(id, plugin);
    await this.db.prepare("UPDATE plugins SET status = ? WHERE id = ?").bind("inactive", id).run();
  }
  /**
   * Mark plugin as errored
   */
  async markError(id, error) {
    const plugin = this.plugins.get(id);
    if (!plugin) throw new Error(`Plugin not found: ${id}`);
    plugin.status = "error";
    plugin.error = error;
    this.updateStatus(id, plugin);
    await this.db.prepare("UPDATE plugins SET status = ?, error_message = ? WHERE id = ?").bind("error", error, id).run();
  }
  /**
   * Get plugin status
   */
  getStatus(id) {
    return this.statuses.get(id);
  }
  /**
   * Get all plugin statuses
   */
  getAllStatuses() {
    return new Map(this.statuses);
  }
  /**
   * Resolve plugin load order based on dependencies
   */
  resolveLoadOrder() {
    const pluginMap = /* @__PURE__ */ new Map();
    for (const [id, manifest] of this.plugins.entries()) {
      pluginMap.set(id, manifest);
    }
    return resolvePluginLoadOrder(pluginMap);
  }
  /**
   * Update plugin status
   */
  updateStatus(id, plugin) {
    const status = {
      id: plugin.id,
      name: plugin.name,
      version: plugin.version,
      active: plugin.status === "active",
      installed: true,
      hasErrors: plugin.status === "error",
      error: plugin.error
    };
    this.statuses.set(id, status);
  }
};

// src/plugins/plugin-validator.ts
var PluginValidator = class {
  /**
   * Validate plugin manifest
   */
  validateManifest(manifest) {
    const result = validateManifest(manifest);
    return {
      valid: result.valid,
      errors: result.errors,
      warnings: []
    };
  }
  /**
   * Validate plugin dependencies
   */
  validateDependencies(manifest, registry) {
    const installedPlugins = new Map(
      registry.getAll().map((p) => [p.id, p])
    );
    const result = validateDependencies(manifest, installedPlugins);
    return {
      valid: result.valid,
      errors: result.errors,
      warnings: []
    };
  }
  /**
   * Validate plugin compatibility with cf-cms.js version
   */
  validateCompatibility(manifest, cfCmsVersion) {
    const errors = [];
    const warnings = [];
    if (!manifest.cfCmsVersion) {
      warnings.push("Plugin does not specify cfCmsVersion compatibility");
      return { valid: true, errors, warnings };
    }
    const [pluginMajor] = manifest.cfCmsVersion.split(".");
    const [cmsMajor] = cfCmsVersion.split(".");
    if (pluginMajor !== cmsMajor) {
      errors.push(
        `Plugin requires cf-cms.js ${manifest.cfCmsVersion}, but ${cfCmsVersion} is installed`
      );
    }
    return { valid: errors.length === 0, errors, warnings };
  }
  /**
   * Validate plugin security
   */
  validateSecurity(manifest) {
    const errors = [];
    const warnings = [];
    if (manifest.id.includes("..") || manifest.id.includes("/")) {
      errors.push("Plugin ID contains invalid characters");
    }
    if (!manifest.author) {
      warnings.push("Plugin does not specify author information");
    }
    if (!manifest.license) {
      warnings.push("Plugin does not specify a license");
    }
    if (!manifest.name || manifest.name.length === 0) {
      errors.push("Plugin name is required");
    }
    if (!manifest.version || !isValidSemver(manifest.version)) {
      errors.push("Plugin version must be valid semantic version (e.g., 1.0.0)");
    }
    return { valid: errors.length === 0, errors, warnings };
  }
  /**
   * Validate complete plugin before installation
   */
  validateForInstallation(manifest, registry, cfCmsVersion) {
    const results = [
      this.validateManifest(manifest),
      this.validateSecurity(manifest),
      this.validateDependencies(manifest, registry),
      this.validateCompatibility(manifest, cfCmsVersion)
    ];
    return {
      valid: results.every((r) => r.valid),
      errors: results.flatMap((r) => r.errors),
      warnings: results.flatMap((r) => r.warnings)
    };
  }
  /**
   * Validate plugin can be uninstalled
   */
  validateForUninstallation(pluginId, registry) {
    const errors = [];
    const warnings = [];
    const dependents = registry.getAll().filter((p) => p.dependencies && p.dependencies[pluginId]);
    if (dependents.length > 0) {
      errors.push(
        `Cannot uninstall: ${dependents.map((p) => p.name).join(", ")} depend on this plugin`
      );
    }
    return { valid: errors.length === 0, errors, warnings };
  }
};
function isValidSemver(version) {
  const semverRegex = /^\d+\.\d+\.\d+(-[a-zA-Z0-9.]+)?(\+[a-zA-Z0-9.]+)?$/;
  return semverRegex.test(version);
}

// src/plugins/hook-system.ts
var HookSystem = class {
  hooks = /* @__PURE__ */ new Map();
  errorHandlers = [];
  /**
   * Register a hook handler
   */
  register(hookName, handler, priority = 10, pluginId = "core") {
    if (!this.hooks.has(hookName)) {
      this.hooks.set(hookName, []);
    }
    const hookList = this.hooks.get(hookName);
    hookList.push({ name: hookName, handler, priority, pluginId });
    hookList.sort((a, b) => a.priority - b.priority);
  }
  /**
   * Execute all handlers for a hook
   */
  async execute(hookName, data, context) {
    const hookList = this.hooks.get(hookName);
    if (!hookList || hookList.length === 0) {
      return data;
    }
    let result = data;
    for (const hook of hookList) {
      try {
        const hookContext = {
          plugin: hook.pluginId,
          context: context || {}
        };
        result = await hook.handler(result, hookContext);
        if (hookContext.cancel) {
          break;
        }
      } catch (error) {
        this.handleError(error, hookName);
      }
    }
    return result;
  }
  /**
   * Execute hooks in parallel (for non-modifying hooks)
   */
  async executeParallel(hookName, data, context) {
    const hookList = this.hooks.get(hookName);
    if (!hookList || hookList.length === 0) {
      return [];
    }
    const promises = hookList.map(async (hook) => {
      try {
        const hookContext = {
          plugin: hook.pluginId,
          context: context || {}
        };
        return await hook.handler(data, hookContext);
      } catch (error) {
        this.handleError(error, hookName);
        return null;
      }
    });
    return Promise.all(promises);
  }
  /**
   * Unregister a hook handler
   */
  unregister(hookName, handler) {
    const hookList = this.hooks.get(hookName);
    if (!hookList) return;
    const index = hookList.findIndex((h) => h.handler === handler);
    if (index !== -1) {
      hookList.splice(index, 1);
    }
  }
  /**
   * Unregister all hooks for a plugin
   */
  unregisterPlugin(pluginId) {
    for (const [, hookList] of this.hooks) {
      const index = hookList.findIndex((h) => h.pluginId === pluginId);
      if (index !== -1) {
        hookList.splice(index, 1);
      }
    }
  }
  /**
   * Get all registered hooks for a name
   */
  getHooks(hookName) {
    return this.hooks.get(hookName) || [];
  }
  /**
   * Get all hooks
   */
  getAllHooks() {
    return new Map(this.hooks);
  }
  /**
   * Register error handler
   */
  onError(handler) {
    this.errorHandlers.push(handler);
  }
  /**
   * Handle hook execution error
   */
  handleError(error, hookName) {
    console.error(`[HookSystem] Error in hook ${hookName}:`, error);
    for (const handler of this.errorHandlers) {
      try {
        handler(error, hookName);
      } catch (e) {
        console.error("[HookSystem] Error in error handler:", e);
      }
    }
  }
  /**
   * Create a scoped hook system for a plugin
   */
  createScope(pluginId) {
    return new ScopedHookSystem(this, pluginId);
  }
};
var ScopedHookSystem = class {
  constructor(parent, pluginId) {
    this.parent = parent;
    this.pluginId = pluginId;
  }
  registeredHooks = [];
  /**
   * Register a hook handler
   */
  register(hookName, handler, priority = 10) {
    this.parent.register(hookName, handler, priority, this.pluginId);
    this.registeredHooks.push({ hookName, handler, priority });
  }
  /**
   * Execute a hook
   */
  async execute(hookName, data, context) {
    return this.parent.execute(hookName, data, context);
  }
  /**
   * Unregister a hook handler
   */
  unregister(hookName, handler) {
    this.parent.unregister(hookName, handler);
    const index = this.registeredHooks.findIndex(
      (h) => h.hookName === hookName && h.handler === handler
    );
    if (index !== -1) {
      this.registeredHooks.splice(index, 1);
    }
  }
  /**
   * Unregister all hooks for this plugin
   */
  unregisterAll() {
    for (const hook of this.registeredHooks) {
      this.parent.unregister(hook.hookName, hook.handler);
    }
    this.registeredHooks = [];
  }
};
var STANDARD_HOOKS = {
  // Application lifecycle
  APP_INIT: "app:init",
  APP_READY: "app:ready",
  APP_SHUTDOWN: "app:shutdown",
  // Request lifecycle
  REQUEST_START: "request:start",
  REQUEST_END: "request:end",
  REQUEST_ERROR: "request:error",
  // Authentication
  AUTH_LOGIN: "auth:login",
  AUTH_LOGOUT: "auth:logout",
  AUTH_REGISTER: "auth:register",
  // Content lifecycle
  CONTENT_BEFORE_CREATE: "content:before:create",
  CONTENT_AFTER_CREATE: "content:after:create",
  CONTENT_BEFORE_UPDATE: "content:before:update",
  CONTENT_AFTER_UPDATE: "content:after:update",
  CONTENT_BEFORE_DELETE: "content:before:delete",
  CONTENT_AFTER_DELETE: "content:after:delete",
  CONTENT_BEFORE_PUBLISH: "content:before:publish",
  CONTENT_AFTER_PUBLISH: "content:after:publish",
  // Media lifecycle
  MEDIA_BEFORE_UPLOAD: "media:before:upload",
  MEDIA_AFTER_UPLOAD: "media:after:upload",
  MEDIA_BEFORE_DELETE: "media:before:delete",
  MEDIA_AFTER_DELETE: "media:after:delete",
  // Plugin lifecycle
  PLUGIN_BEFORE_INSTALL: "plugin:before:install",
  PLUGIN_AFTER_INSTALL: "plugin:after:install",
  PLUGIN_BEFORE_UNINSTALL: "plugin:before:uninstall",
  PLUGIN_AFTER_UNINSTALL: "plugin:after:uninstall",
  PLUGIN_BEFORE_ACTIVATE: "plugin:before:activate",
  PLUGIN_AFTER_ACTIVATE: "plugin:after:activate",
  PLUGIN_BEFORE_DEACTIVATE: "plugin:before:deactivate",
  PLUGIN_AFTER_DEACTIVATE: "plugin:after:deactivate",
  // Admin interface
  ADMIN_MENU_RENDER: "admin:menu:render",
  ADMIN_PAGE_RENDER: "admin:page:render",
  ADMIN_DASHBOARD_RENDER: "admin:dashboard:render",
  // Database
  DB_BEFORE_MIGRATE: "db:before:migrate",
  DB_AFTER_MIGRATE: "db:after:migrate",
  DB_BEFORE_SEED: "db:before:seed",
  DB_AFTER_SEED: "db:after:seed"
};

// src/plugins/route-registry.ts
var RouteRegistry = class {
  db;
  routes = /* @__PURE__ */ new Map();
  routesByPlugin = /* @__PURE__ */ new Map();
  app = null;
  constructor(options) {
    this.db = options.db;
  }
  /**
   * Set the Hono app instance for route registration
   */
  setApp(app) {
    this.app = app;
  }
  /**
   * Register a route
   */
  async registerRoute(pluginId, path, method, handler, options) {
    for (const route2 of this.routes.values()) {
      if (route2.method === method && route2.path === path && route2.pluginId !== pluginId) {
        throw new Error(
          `Route conflict: ${method} ${path} already registered by ${route2.pluginId}`
        );
      }
    }
    const routeId = `${pluginId}:${method}:${path}`;
    const route = {
      id: routeId,
      pluginId,
      path,
      method,
      handler,
      middleware: options?.middleware,
      requiresAuth: options?.requiresAuth,
      permissions: options?.permissions,
      active: true
    };
    this.routes.set(routeId, route);
    if (!this.routesByPlugin.has(pluginId)) {
      this.routesByPlugin.set(pluginId, []);
    }
    this.routesByPlugin.get(pluginId).push(routeId);
    if (this.app) {
      this.registerWithApp(route);
    }
    await this.db.prepare(`
        INSERT OR REPLACE INTO plugin_routes 
        (id, plugin_id, path, method, handler_name, is_active)
        VALUES (?, ?, ?, ?, ?, ?)
      `).bind(routeId, pluginId, path, method, handler.name || "handler", true).run();
  }
  /**
   * Unregister a route
   */
  async unregisterRoute(routeId) {
    const route = this.routes.get(routeId);
    if (!route) return;
    this.routes.delete(routeId);
    const pluginRoutes = this.routesByPlugin.get(route.pluginId);
    if (pluginRoutes) {
      const index = pluginRoutes.indexOf(routeId);
      if (index !== -1) {
        pluginRoutes.splice(index, 1);
      }
    }
    await this.db.prepare("UPDATE plugin_routes SET is_active = ? WHERE id = ?").bind(false, routeId).run();
  }
  /**
   * Unregister all routes for a plugin
   */
  async unregisterPluginRoutes(pluginId) {
    const routeIds = this.routesByPlugin.get(pluginId) || [];
    for (const routeId of routeIds) {
      await this.unregisterRoute(routeId);
    }
    this.routesByPlugin.delete(pluginId);
  }
  /**
   * Get a route
   */
  getRoute(routeId) {
    return this.routes.get(routeId);
  }
  /**
   * Get all routes
   */
  getAllRoutes() {
    return Array.from(this.routes.values());
  }
  /**
   * Get routes for a plugin
   */
  getPluginRoutes(pluginId) {
    const routeIds = this.routesByPlugin.get(pluginId) || [];
    return routeIds.map((id) => this.routes.get(id)).filter(Boolean);
  }
  /**
   * Get active routes
   */
  getActiveRoutes() {
    return Array.from(this.routes.values()).filter((r) => r.active);
  }
  /**
   * Enable a route
   */
  async enableRoute(routeId) {
    const route = this.routes.get(routeId);
    if (!route) return;
    route.active = true;
    await this.db.prepare("UPDATE plugin_routes SET is_active = ? WHERE id = ?").bind(true, routeId).run();
  }
  /**
   * Disable a route
   */
  async disableRoute(routeId) {
    const route = this.routes.get(routeId);
    if (!route) return;
    route.active = false;
    await this.db.prepare("UPDATE plugin_routes SET is_active = ? WHERE id = ?").bind(false, routeId).run();
  }
  /**
   * Register route with Hono app
   */
  registerWithApp(route) {
    if (!this.app) return;
    const wrappedHandler = async (c) => {
      if (route.middleware) {
        for (const mw of route.middleware) {
          await mw(c, async () => {
          });
        }
      }
      return route.handler(c);
    };
    switch (route.method) {
      case "GET":
        this.app.get(route.path, wrappedHandler);
        break;
      case "POST":
        this.app.post(route.path, wrappedHandler);
        break;
      case "PUT":
        this.app.put(route.path, wrappedHandler);
        break;
      case "DELETE":
        this.app.delete(route.path, wrappedHandler);
        break;
      case "PATCH":
        this.app.patch(route.path, wrappedHandler);
        break;
    }
  }
  /**
   * Load routes from database
   */
  async loadFromDatabase() {
    try {
      const result = await this.db.prepare("SELECT * FROM plugin_routes WHERE is_active = ?").bind(true).all();
      if (result.results) {
        for (const row of result.results) {
        }
      }
    } catch (error) {
      console.error("[RouteRegistry] Failed to load routes from database:", error);
    }
  }
};

// src/plugins/admin-ui-registry.ts
var AdminUIRegistry = class {
  db;
  pages = /* @__PURE__ */ new Map();
  menuItems = /* @__PURE__ */ new Map();
  extensions = /* @__PURE__ */ new Map();
  pagesByPlugin = /* @__PURE__ */ new Map();
  menuItemsByPlugin = /* @__PURE__ */ new Map();
  extensionsByPlugin = /* @__PURE__ */ new Map();
  constructor(options) {
    this.db = options.db;
  }
  /**
   * Register an admin page
   */
  async registerPage(pluginId, path, title, component, options) {
    const pageId = `${pluginId}:${path}`;
    const page = {
      id: pageId,
      pluginId,
      path,
      title,
      icon: options?.icon,
      description: options?.description,
      permissions: options?.permissions,
      component,
      active: true
    };
    if (options?.menuItem) {
      const menuItemId = `${pluginId}:menu:${path}`;
      const menuItem = {
        id: menuItemId,
        label: options.menuItem.label,
        path: options.menuItem.path || path,
        icon: options.menuItem.icon,
        order: options.menuItem.order,
        parent: options.menuItem.parent,
        permissions: options.menuItem.permissions,
        active: true
      };
      this.menuItems.set(menuItemId, menuItem);
      if (!this.menuItemsByPlugin.has(pluginId)) {
        this.menuItemsByPlugin.set(pluginId, []);
      }
      this.menuItemsByPlugin.get(pluginId).push(menuItemId);
      page.menuItem = menuItem;
    }
    this.pages.set(pageId, page);
    if (!this.pagesByPlugin.has(pluginId)) {
      this.pagesByPlugin.set(pluginId, []);
    }
    this.pagesByPlugin.get(pluginId).push(pageId);
    await this.db.prepare(`
        INSERT OR REPLACE INTO admin_pages 
        (id, plugin_id, path, title, icon, description, permissions, component, active)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
      `).bind(
      pageId,
      pluginId,
      path,
      title,
      options?.icon || null,
      options?.description || null,
      options?.permissions ? JSON.stringify(options.permissions) : null,
      component,
      true
    ).run();
  }
  /**
   * Register a menu item
   */
  async registerMenuItem(pluginId, label, path, options) {
    const menuItemId = `${pluginId}:menu:${path}`;
    const menuItem = {
      id: menuItemId,
      label,
      path,
      icon: options?.icon,
      order: options?.order,
      parent: options?.parent,
      permissions: options?.permissions,
      active: true
    };
    this.menuItems.set(menuItemId, menuItem);
    if (!this.menuItemsByPlugin.has(pluginId)) {
      this.menuItemsByPlugin.set(pluginId, []);
    }
    this.menuItemsByPlugin.get(pluginId).push(menuItemId);
    await this.db.prepare(`
        INSERT OR REPLACE INTO admin_menu_items 
        (id, plugin_id, label, path, icon, order_index, parent, permissions, active)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
      `).bind(
      menuItemId,
      pluginId,
      label,
      path,
      options?.icon || null,
      options?.order || 100,
      options?.parent || null,
      options?.permissions ? JSON.stringify(options.permissions) : null,
      true
    ).run();
  }
  /**
   * Register a UI extension point
   */
  async registerExtension(pluginId, extensionPoint, component, order) {
    const extensionId = `${pluginId}:ext:${extensionPoint}`;
    const extension = {
      id: extensionId,
      pluginId,
      extensionPoint,
      component,
      order: order || 100,
      active: true
    };
    this.extensions.set(extensionId, extension);
    if (!this.extensionsByPlugin.has(pluginId)) {
      this.extensionsByPlugin.set(pluginId, []);
    }
    this.extensionsByPlugin.get(pluginId).push(extensionId);
    await this.db.prepare(`
        INSERT OR REPLACE INTO admin_extensions 
        (id, plugin_id, extension_point, component, order_index, active)
        VALUES (?, ?, ?, ?, ?, ?)
      `).bind(extensionId, pluginId, extensionPoint, component, order || 100, true).run();
  }
  /**
   * Unregister all admin UI elements for a plugin
   */
  async unregisterPlugin(pluginId) {
    const pageIds = this.pagesByPlugin.get(pluginId) || [];
    for (const pageId of pageIds) {
      this.pages.delete(pageId);
    }
    this.pagesByPlugin.delete(pluginId);
    const menuItemIds = this.menuItemsByPlugin.get(pluginId) || [];
    for (const menuItemId of menuItemIds) {
      this.menuItems.delete(menuItemId);
    }
    this.menuItemsByPlugin.delete(pluginId);
    const extensionIds = this.extensionsByPlugin.get(pluginId) || [];
    for (const extensionId of extensionIds) {
      this.extensions.delete(extensionId);
    }
    this.extensionsByPlugin.delete(pluginId);
    await this.db.prepare("UPDATE admin_pages SET active = ? WHERE plugin_id = ?").bind(false, pluginId).run();
    await this.db.prepare("UPDATE admin_menu_items SET active = ? WHERE plugin_id = ?").bind(false, pluginId).run();
    await this.db.prepare("UPDATE admin_extensions SET active = ? WHERE plugin_id = ?").bind(false, pluginId).run();
  }
  /**
   * Get all admin pages
   */
  getPages() {
    return Array.from(this.pages.values()).filter((p) => p.active);
  }
  /**
   * Get pages for a plugin
   */
  getPluginPages(pluginId) {
    const pageIds = this.pagesByPlugin.get(pluginId) || [];
    return pageIds.map((id) => this.pages.get(id)).filter((p) => p && p.active);
  }
  /**
   * Get all menu items
   */
  getMenuItems() {
    return Array.from(this.menuItems.values()).filter((m) => m.active);
  }
  /**
   * Get menu items for a plugin
   */
  getPluginMenuItems(pluginId) {
    const menuItemIds = this.menuItemsByPlugin.get(pluginId) || [];
    return menuItemIds.map((id) => this.menuItems.get(id)).filter((m) => m && m.active);
  }
  /**
   * Get extensions for an extension point
   */
  getExtensions(extensionPoint) {
    return Array.from(this.extensions.values()).filter((e) => e.extensionPoint === extensionPoint && e.active).sort((a, b) => (a.order || 100) - (b.order || 100));
  }
  /**
   * Get all extensions
   */
  getAllExtensions() {
    return Array.from(this.extensions.values()).filter((e) => e.active);
  }
  /**
   * Render menu HTML
   */
  renderMenu(userPermissions = []) {
    const items = this.getMenuItems().filter((item) => {
      if (!item.permissions || item.permissions.length === 0) return true;
      return item.permissions.some((p) => userPermissions.includes(p));
    }).sort((a, b) => (a.order || 100) - (b.order || 100));
    let html = '<ul class="admin-menu">';
    for (const item of items) {
      html += `
        <li class="admin-menu-item">
          <a href="${item.path}" class="admin-menu-link">
            ${item.icon ? `<span class="icon">${item.icon}</span>` : ""}
            <span class="label">${item.label}</span>
          </a>
        </li>
      `;
    }
    html += "</ul>";
    return html;
  }
  /**
   * Load from database
   */
  async loadFromDatabase() {
    try {
      const pagesResult = await this.db.prepare("SELECT * FROM admin_pages WHERE active = ?").bind(true).all();
      if (pagesResult.results) {
        for (const row of pagesResult.results) {
          const page = {
            id: row.id,
            pluginId: row.plugin_id,
            path: row.path,
            title: row.title,
            icon: row.icon,
            description: row.description,
            permissions: row.permissions ? JSON.parse(row.permissions) : void 0,
            component: row.component,
            active: true
          };
          this.pages.set(page.id, page);
        }
      }
      const menuResult = await this.db.prepare("SELECT * FROM admin_menu_items WHERE active = ?").bind(true).all();
      if (menuResult.results) {
        for (const row of menuResult.results) {
          const menuItem = {
            id: row.id,
            label: row.label,
            path: row.path,
            icon: row.icon,
            order: row.order_index,
            parent: row.parent,
            permissions: row.permissions ? JSON.parse(row.permissions) : void 0,
            active: true
          };
          this.menuItems.set(menuItem.id, menuItem);
        }
      }
      const extResult = await this.db.prepare("SELECT * FROM admin_extensions WHERE active = ?").bind(true).all();
      if (extResult.results) {
        for (const row of extResult.results) {
          const extension = {
            id: row.id,
            pluginId: row.plugin_id,
            extensionPoint: row.extension_point,
            component: row.component,
            order: row.order_index,
            active: true
          };
          this.extensions.set(extension.id, extension);
        }
      }
    } catch (error) {
      console.error("[AdminUIRegistry] Failed to load from database:", error);
    }
  }
};

// src/plugins/plugin-manager.ts
var PluginManager = class {
  db;
  kv;
  r2;
  cfCmsVersion;
  registry;
  validator;
  hooks;
  routes;
  adminUI;
  loadedPlugins = /* @__PURE__ */ new Map();
  pluginContexts = /* @__PURE__ */ new Map();
  constructor(options) {
    this.db = options.db;
    this.kv = options.kv;
    this.r2 = options.r2;
    this.cfCmsVersion = options.cfCmsVersion;
    this.registry = new PluginRegistry({ db: this.db });
    this.validator = new PluginValidator();
    this.hooks = new HookSystem();
    this.routes = new RouteRegistry({ db: this.db });
    this.adminUI = new AdminUIRegistry({ db: this.db });
  }
  /**
   * Initialize plugin system
   */
  async initialize() {
    console.log("[PluginManager] Initializing plugin system...");
    try {
      await this.registry.initialize();
      await this.adminUI.loadFromDatabase();
      await this.routes.loadFromDatabase();
      await this.hooks.execute(STANDARD_HOOKS.APP_INIT, {});
      console.log("[PluginManager] Plugin system initialized successfully");
    } catch (error) {
      console.error("[PluginManager] Failed to initialize:", error);
      throw error;
    }
  }
  /**
   * Load plugins in dependency order
   */
  async loadPlugins() {
    console.log("[PluginManager] Loading plugins...");
    const { order, errors } = this.registry.resolveLoadOrder();
    if (errors.length > 0) {
      console.error("[PluginManager] Plugin dependency errors:", errors);
    }
    for (const pluginId of order) {
      try {
        await this.loadPlugin(pluginId);
      } catch (error) {
        console.error(`[PluginManager] Failed to load plugin ${pluginId}:`, error);
        await this.registry.markError(pluginId, String(error));
      }
    }
    await this.hooks.execute(STANDARD_HOOKS.APP_READY, {});
    console.log("[PluginManager] Plugins loaded successfully");
  }
  /**
   * Load a single plugin
   */
  async loadPlugin(pluginId) {
    const manifest = this.registry.get(pluginId);
    if (!manifest) throw new Error(`Plugin not found: ${pluginId}`);
    if (manifest.status !== "active") {
      console.log(`[PluginManager] Skipping inactive plugin: ${pluginId}`);
      return;
    }
    if (this.loadedPlugins.has(pluginId)) {
      console.log(`[PluginManager] Plugin already loaded: ${pluginId}`);
      return;
    }
    console.log(`[PluginManager] Loading plugin: ${pluginId}`);
    try {
      const context = this.createPluginContext(manifest);
      this.pluginContexts.set(pluginId, context);
      await this.hooks.execute(STANDARD_HOOKS.PLUGIN_BEFORE_ACTIVATE, { pluginId });
      const plugin = this.loadedPlugins.get(pluginId);
      if (!plugin) {
        throw new Error(`Plugin module not found: ${pluginId}`);
      }
      if (plugin.activate) {
        await plugin.activate(context);
      }
      if (plugin.routes) {
        for (const route of plugin.routes) {
          await this.routes.registerRoute(
            pluginId,
            route.path,
            route.method || "GET",
            route.handler,
            {
              middleware: route.middleware,
              requiresAuth: route.requiresAuth,
              permissions: route.permissions
            }
          );
        }
      }
      if (plugin.hooks) {
        const scopedHooks = this.hooks.createScope(pluginId);
        for (const hook of plugin.hooks) {
          scopedHooks.register(hook.name, hook.handler, hook.priority);
        }
      }
      if (plugin.adminPages) {
        for (const page of plugin.adminPages) {
          await this.adminUI.registerPage(
            pluginId,
            page.path,
            page.title,
            page.component,
            {
              icon: page.icon,
              description: page.description,
              permissions: page.permissions,
              menuItem: page.menuItem
            }
          );
        }
      }
      await this.hooks.execute(STANDARD_HOOKS.PLUGIN_AFTER_ACTIVATE, { pluginId });
      console.log(`[PluginManager] Plugin loaded successfully: ${pluginId}`);
    } catch (error) {
      console.error(`[PluginManager] Error loading plugin ${pluginId}:`, error);
      await this.registry.markError(pluginId, String(error));
      throw error;
    }
  }
  /**
   * Install a plugin
   */
  async installPlugin(manifest, path, entry) {
    console.log(`[PluginManager] Installing plugin: ${manifest.id}`);
    try {
      const validation = this.validator.validateForInstallation(
        manifest,
        this.registry,
        this.cfCmsVersion
      );
      if (!validation.valid) {
        throw new Error(`Plugin validation failed: ${validation.errors.join(", ")}`);
      }
      await this.hooks.execute(STANDARD_HOOKS.PLUGIN_BEFORE_INSTALL, { manifest });
      await this.registry.register(manifest, path, entry);
      await this.hooks.execute(STANDARD_HOOKS.PLUGIN_AFTER_INSTALL, { manifest });
      console.log(`[PluginManager] Plugin installed successfully: ${manifest.id}`);
    } catch (error) {
      console.error(`[PluginManager] Failed to install plugin:`, error);
      throw error;
    }
  }
  /**
   * Uninstall a plugin
   */
  async uninstallPlugin(pluginId) {
    console.log(`[PluginManager] Uninstalling plugin: ${pluginId}`);
    try {
      const validation = this.validator.validateForUninstallation(pluginId, this.registry);
      if (!validation.valid) {
        throw new Error(`Cannot uninstall: ${validation.errors.join(", ")}`);
      }
      await this.hooks.execute(STANDARD_HOOKS.PLUGIN_BEFORE_UNINSTALL, { pluginId });
      await this.registry.deactivate(pluginId);
      await this.routes.unregisterPluginRoutes(pluginId);
      await this.adminUI.unregisterPlugin(pluginId);
      this.hooks.unregisterPlugin(pluginId);
      const plugin = this.loadedPlugins.get(pluginId);
      if (plugin && plugin.uninstall) {
        const context = this.pluginContexts.get(pluginId);
        if (context) {
          await plugin.uninstall(context);
        }
      }
      await this.registry.unregister(pluginId);
      this.loadedPlugins.delete(pluginId);
      this.pluginContexts.delete(pluginId);
      await this.hooks.execute(STANDARD_HOOKS.PLUGIN_AFTER_UNINSTALL, { pluginId });
      console.log(`[PluginManager] Plugin uninstalled successfully: ${pluginId}`);
    } catch (error) {
      console.error(`[PluginManager] Failed to uninstall plugin:`, error);
      throw error;
    }
  }
  /**
   * Activate a plugin
   */
  async activatePlugin(pluginId) {
    await this.registry.activate(pluginId);
    await this.loadPlugin(pluginId);
  }
  /**
   * Deactivate a plugin
   */
  async deactivatePlugin(pluginId) {
    await this.hooks.execute(STANDARD_HOOKS.PLUGIN_BEFORE_DEACTIVATE, { pluginId });
    const plugin = this.loadedPlugins.get(pluginId);
    if (plugin && plugin.deactivate) {
      const context = this.pluginContexts.get(pluginId);
      if (context) {
        await plugin.deactivate(context);
      }
    }
    await this.routes.unregisterPluginRoutes(pluginId);
    this.hooks.unregisterPlugin(pluginId);
    await this.registry.deactivate(pluginId);
    await this.hooks.execute(STANDARD_HOOKS.PLUGIN_AFTER_DEACTIVATE, { pluginId });
  }
  /**
   * Register a loaded plugin
   */
  registerLoadedPlugin(pluginId, plugin) {
    this.loadedPlugins.set(pluginId, plugin);
  }
  /**
   * Create plugin context
   */
  createPluginContext(manifest) {
    const pluginId = manifest.id;
    const scopedHooks = this.hooks.createScope(pluginId);
    return {
      db: this.db,
      kv: this.kv,
      r2: this.r2,
      config: {
        enabled: true,
        installedAt: manifest.installedAt,
        updatedAt: manifest.updatedAt
      },
      services: {
        auth: {},
        content: {},
        media: {}
      },
      hooks: scopedHooks,
      logger: {
        debug: (msg, data) => console.debug(`[${pluginId}] ${msg}`, data),
        info: (msg, data) => console.info(`[${pluginId}] ${msg}`, data),
        warn: (msg, data) => console.warn(`[${pluginId}] ${msg}`, data),
        error: (msg, err, data) => console.error(`[${pluginId}] ${msg}`, err, data)
      }
    };
  }
  /**
   * Get plugin status
   */
  getPluginStatus(pluginId) {
    return this.registry.getStatus(pluginId);
  }
  /**
   * Get all plugin statuses
   */
  getAllPluginStatuses() {
    return this.registry.getAllStatuses();
  }
};

// src/plugins/hot-reload.ts
var HotReloadManager = class {
  watchers = /* @__PURE__ */ new Map();
  pluginManager;
  options;
  reloadQueue = /* @__PURE__ */ new Set();
  debounceTimer = null;
  constructor(pluginManager, options = {}) {
    this.pluginManager = pluginManager;
    this.options = {
      enabled: this.isDevelopment(),
      watchPaths: ["./src/plugins", "./plugins"],
      debounceMs: 300,
      excludePatterns: [/node_modules/, /\.git/, /dist/, /\.d\.ts$/],
      ...options
    };
  }
  isDevelopment() {
    try {
      return typeof process !== "undefined" && process.env?.NODE_ENV === "development";
    } catch {
      return false;
    }
  }
  /**
   * Start hot reload system
   */
  async start() {
    if (!this.options.enabled) {
      console.log("\u{1F525} Hot reload disabled (not in development mode)");
      return;
    }
    console.log("\u{1F525} Starting hot reload system...");
    try {
      const chokidar = await import('./esm-TUECOQFJ.cjs');
      for (const watchPath of this.options.watchPaths) {
        const watcher = chokidar.watch(watchPath, {
          ignored: this.options.excludePatterns,
          persistent: true,
          ignoreInitial: true
        });
        watcher.on("add", (path) => this.handleFileChange("added", path)).on("change", (path) => this.handleFileChange("changed", path)).on("unlink", (path) => this.handleFileChange("removed", path));
        this.watchers.set(watchPath, watcher);
        console.log(`\u{1F440} Watching ${watchPath} for plugin changes`);
      }
      console.log("\u{1F525} Hot reload system started");
    } catch (error) {
      console.warn("\u26A0\uFE0F Hot reload not available (chokidar not installed):", error);
    }
  }
  /**
   * Stop hot reload system
   */
  async stop() {
    console.log("\u{1F525} Stopping hot reload system...");
    for (const [path, watcher] of this.watchers.entries()) {
      await watcher.close();
      console.log(`\u{1F44B} Stopped watching ${path}`);
    }
    this.watchers.clear();
    if (this.debounceTimer) {
      clearTimeout(this.debounceTimer);
      this.debounceTimer = null;
    }
    console.log("\u{1F525} Hot reload system stopped");
  }
  /**
   * Manually reload a plugin
   */
  async reloadPlugin(pluginId) {
    try {
      console.log(`\u{1F504} Manually reloading plugin: ${pluginId}`);
      console.log(`\u2705 Plugin reload requested: ${pluginId}`);
      return true;
    } catch (error) {
      console.error(`\u274C Failed to reload plugin ${pluginId}:`, error);
      return false;
    }
  }
  /**
   * Get hot reload status
   */
  getStatus() {
    return {
      enabled: this.options.enabled,
      watchedPaths: Array.from(this.watchers.keys()),
      queuedReloads: Array.from(this.reloadQueue),
      isWatching: this.watchers.size > 0
    };
  }
  handleFileChange(type, filePath) {
    console.log(`\u{1F4C1} File ${type}: ${filePath}`);
    const pluginId = this.extractPluginId(filePath);
    if (!pluginId) {
      console.log(`\u26A0\uFE0F Could not determine plugin ID for ${filePath}`);
      return;
    }
    this.reloadQueue.add(pluginId);
    if (this.debounceTimer) {
      clearTimeout(this.debounceTimer);
    }
    this.debounceTimer = setTimeout(() => {
      this.processReloadQueue();
    }, this.options.debounceMs);
  }
  async processReloadQueue() {
    if (this.reloadQueue.size === 0) return;
    console.log(`\u{1F504} Processing reload queue: ${Array.from(this.reloadQueue).join(", ")}`);
    const reloadPromises = Array.from(this.reloadQueue).map(async (pluginId) => {
      try {
        await this.reloadPlugin(pluginId);
      } catch (error) {
        console.error(`\u274C Failed to reload ${pluginId}:`, error);
      }
    });
    await Promise.allSettled(reloadPromises);
    this.reloadQueue.clear();
  }
  extractPluginId(filePath) {
    const patterns = [
      /\/plugins\/([^\/]+)\//,
      // /plugins/plugin-name/
      /\/src\/plugins\/([^\/]+)\//,
      // /src/plugins/plugin-name/
      /\/([^\/]+)\/plugin\.js$/,
      // /plugin-name/plugin.js
      /\/([^\/]+)\/index\.(js|ts)$/,
      // /plugin-name/index.js
      /\/([^\/]+)\/manifest\.json$/
      // /plugin-name/manifest.json
    ];
    for (const pattern of patterns) {
      const match = filePath.match(pattern);
      if (match && match[1]) {
        return match[1];
      }
    }
    return null;
  }
};
function createHotReloadMiddleware(hotReloadManager) {
  return async (c, next) => {
    c.set("hotReload", hotReloadManager.getStatus());
    c.set("reloadPlugin", (pluginId) => hotReloadManager.reloadPlugin(pluginId));
    await next();
  };
}
function createHotReloadRoutes(hotReloadManager) {
  return {
    // Get hot reload status
    getStatus: async (c) => {
      return c.json(hotReloadManager.getStatus());
    },
    // Reload specific plugin
    reloadPlugin: async (c) => {
      const { pluginId } = c.req.param();
      const success = await hotReloadManager.reloadPlugin(pluginId);
      return c.json({
        success,
        message: success ? `Plugin ${pluginId} reloaded` : `Failed to reload ${pluginId}`
      });
    },
    // Reload all plugins
    reloadAll: async (c) => {
      return c.json({
        total: 0,
        successful: 0,
        failed: 0
      });
    }
  };
}

// src/plugins/plugin-api-3.0.ts
function createPlugin(definition) {
  validatePluginDefinition(definition);
  const plugin = {
    ...definition,
    sandbox: {
      enabled: false,
      ...definition.sandbox
    },
    permissions: {
      required: [],
      optional: [],
      defines: [],
      ...definition.permissions
    }
  };
  return plugin;
}
function validatePluginDefinition(definition) {
  if (!definition.id) {
    throw new Error("Plugin ID is required");
  }
  if (!definition.name) {
    throw new Error("Plugin name is required");
  }
  if (!definition.version) {
    throw new Error("Plugin version is required");
  }
  if (!/^[a-z0-9-]+$/.test(definition.id)) {
    throw new Error("Plugin ID must contain only lowercase letters, numbers, and hyphens");
  }
  if (!/^\d+\.\d+\.\d+/.test(definition.version)) {
    throw new Error("Plugin version must follow semantic versioning (x.y.z)");
  }
}
var PluginAPIUtils = {
  /**
   * Create a route handler with automatic error handling
   */
  createRouteHandler(handler) {
    return async (context) => {
      try {
        return await handler(context);
      } catch (error) {
        context.plugin.logger.error("Route handler error:", error);
        throw error;
      }
    };
  },
  /**
   * Create a hook handler with automatic error handling
   */
  createHookHandler(handler) {
    return async (data, context) => {
      try {
        return await handler(data, context);
      } catch (error) {
        context.logger.error("Hook handler error:", error);
        return data;
      }
    };
  },
  /**
   * Create a middleware function with automatic error handling
   */
  createMiddleware(handler) {
    return async (context, next) => {
      try {
        await handler(context, next);
      } catch (error) {
        context.plugin.logger.error("Middleware error:", error);
        throw error;
      }
    };
  }
};

// src/plugins/plugin-validator-3.0.ts
var PluginValidator3 = class {
  options;
  constructor(options = {}) {
    this.options = {
      strict: false,
      allowUnsafe: false,
      checkDependencies: true,
      validateCode: true,
      securityScan: true,
      ...options
    };
  }
  /**
   * Validate a plugin definition
   */
  async validate(plugin) {
    const result = {
      valid: true,
      errors: [],
      warnings: [],
      score: 100
    };
    this.validateBasicStructure(plugin, result);
    this.validatePermissions(plugin.permissions, result);
    if (this.options.checkDependencies) {
      await this.validateDependencies(plugin.dependencies, result);
    }
    if (this.options.securityScan) {
      this.validateSecurity(plugin, result);
    }
    if (this.options.validateCode) {
      this.validateCode(plugin, result);
    }
    result.score = this.calculateScore(result);
    result.valid = result.errors.length === 0 && result.score >= 50;
    return result;
  }
  /**
   * Validate basic plugin structure
   */
  validateBasicStructure(plugin, result) {
    if (!plugin.id) {
      result.errors.push({
        code: "MISSING_ID",
        message: "Plugin ID is required",
        severity: "critical",
        field: "id"
      });
    }
    if (!plugin.name) {
      result.errors.push({
        code: "MISSING_NAME",
        message: "Plugin name is required",
        severity: "critical",
        field: "name"
      });
    }
    if (!plugin.version) {
      result.errors.push({
        code: "MISSING_VERSION",
        message: "Plugin version is required",
        severity: "critical",
        field: "version"
      });
    }
    if (plugin.id && !/^[a-z0-9-]+$/.test(plugin.id)) {
      result.errors.push({
        code: "INVALID_ID_FORMAT",
        message: "Plugin ID must contain only lowercase letters, numbers, and hyphens",
        severity: "high",
        field: "id",
        suggestion: "Use kebab-case format (e.g., my-awesome-plugin)"
      });
    }
    if (plugin.version && !/^\d+\.\d+\.\d+/.test(plugin.version)) {
      result.errors.push({
        code: "INVALID_VERSION_FORMAT",
        message: "Plugin version must follow semantic versioning",
        severity: "high",
        field: "version",
        suggestion: "Use format x.y.z (e.g., 1.0.0)"
      });
    }
    if (plugin.name && plugin.name.length > 50) {
      result.warnings.push({
        code: "LONG_NAME",
        message: "Plugin name is quite long",
        field: "name",
        suggestion: "Consider using a shorter, more concise name"
      });
    }
    if (!plugin.description) {
      result.warnings.push({
        code: "MISSING_DESCRIPTION",
        message: "Plugin description is recommended",
        field: "description",
        suggestion: "Add a clear description of what your plugin does"
      });
    }
    if (!plugin.author) {
      result.warnings.push({
        code: "MISSING_AUTHOR",
        message: "Plugin author information is recommended",
        field: "author",
        suggestion: "Add author information for better plugin discoverability"
      });
    }
    if (!plugin.license) {
      result.warnings.push({
        code: "MISSING_LICENSE",
        message: "Plugin license is recommended",
        field: "license",
        suggestion: "Specify a license (e.g., MIT, Apache-2.0)"
      });
    }
  }
  /**
   * Validate plugin permissions
   */
  validatePermissions(permissions, result) {
    if (!permissions) return;
    const dangerousPermissions = [
      "system:admin",
      "file:write-all",
      "network:unrestricted",
      "database:raw-query"
    ];
    if (permissions.required) {
      for (const permission of permissions.required) {
        if (dangerousPermissions.includes(permission)) {
          if (this.options.allowUnsafe) {
            result.warnings.push({
              code: "DANGEROUS_PERMISSION",
              message: `Permission '${permission}' is potentially dangerous`,
              suggestion: "Ensure this permission is absolutely necessary"
            });
          } else {
            result.errors.push({
              code: "UNSAFE_PERMISSION",
              message: `Permission '${permission}' is not allowed`,
              severity: "high",
              suggestion: "Use more specific, limited permissions"
            });
          }
        }
      }
    }
    const totalPermissions = (permissions.required?.length || 0) + (permissions.optional?.length || 0);
    if (totalPermissions > 10) {
      result.warnings.push({
        code: "EXCESSIVE_PERMISSIONS",
        message: "Plugin requests many permissions",
        suggestion: "Consider if all permissions are necessary"
      });
    }
    if (permissions.defines) {
      for (const perm of permissions.defines) {
        if (!perm.name || !perm.description) {
          result.errors.push({
            code: "INVALID_PERMISSION_DEFINITION",
            message: "Custom permissions must have name and description",
            severity: "medium"
          });
        }
      }
    }
  }
  /**
   * Validate plugin dependencies
   */
  async validateDependencies(dependencies, result) {
    if (!dependencies) return;
    if (dependencies.cfCms) {
      if (!this.isValidVersionRange(dependencies.cfCms)) {
        result.errors.push({
          code: "INVALID_CMS_VERSION",
          message: "Invalid CF-CMS version requirement",
          severity: "high",
          field: "dependencies.cfCms",
          suggestion: "Use valid semver range (e.g., ^3.0.0)"
        });
      }
    }
    if (dependencies.plugins) {
      for (const [pluginId, version] of Object.entries(dependencies.plugins)) {
        if (!this.isValidVersionRange(version)) {
          result.errors.push({
            code: "INVALID_PLUGIN_VERSION",
            message: `Invalid version requirement for plugin '${pluginId}'`,
            severity: "medium",
            suggestion: "Use valid semver range"
          });
        }
      }
    }
    if (dependencies.plugins) {
      const pluginCount = Object.keys(dependencies.plugins).length;
      if (pluginCount > 5) {
        result.warnings.push({
          code: "MANY_DEPENDENCIES",
          message: "Plugin has many dependencies",
          suggestion: "Consider reducing dependencies for better performance"
        });
      }
    }
  }
  /**
   * Validate plugin security
   */
  validateSecurity(plugin, result) {
    if (plugin.routes?.api) {
      for (const route of plugin.routes.api) {
        if (!route.permissions && !route.middleware?.some((m) => m.name?.includes("auth"))) {
          result.warnings.push({
            code: "UNPROTECTED_ROUTE",
            message: `Route ${route.method} ${route.path} has no authentication`,
            suggestion: "Add authentication middleware or permissions"
          });
        }
        if (route.path.includes(":") && !route.middleware?.some((m) => m.name?.includes("validate"))) {
          result.warnings.push({
            code: "UNVALIDATED_PARAMS",
            message: `Route ${route.path} has parameters but no validation`,
            suggestion: "Add parameter validation middleware"
          });
        }
      }
    }
    if (plugin.sandbox?.enabled === false && !this.options.allowUnsafe) {
      result.warnings.push({
        code: "SANDBOX_DISABLED",
        message: "Plugin has sandboxing disabled",
        suggestion: "Enable sandboxing for better security"
      });
    }
    if (plugin.configuration?.schema) {
      for (const [key, field] of Object.entries(plugin.configuration.schema)) {
        if (field.sensitive && !field.validation?.some((v) => v.type === "required")) {
          result.warnings.push({
            code: "OPTIONAL_SENSITIVE_CONFIG",
            message: `Sensitive configuration '${key}' is not required`,
            suggestion: "Make sensitive configuration required or provide secure defaults"
          });
        }
      }
    }
  }
  /**
   * Validate plugin code structure
   */
  validateCode(plugin, result) {
    const hasLifecycleHooks = !!(plugin.onInstall || plugin.onEnable || plugin.onDisable || plugin.onUninstall);
    if (!hasLifecycleHooks) {
      result.warnings.push({
        code: "NO_LIFECYCLE_HOOKS",
        message: "Plugin has no lifecycle hooks",
        suggestion: "Consider adding lifecycle hooks for proper setup/cleanup"
      });
    }
    const hasFunctionality = !!(plugin.routes || plugin.hooks || plugin.adminUI || plugin.services);
    if (!hasFunctionality) {
      result.warnings.push({
        code: "NO_FUNCTIONALITY",
        message: "Plugin appears to have no functionality",
        suggestion: "Add routes, hooks, admin UI, or services"
      });
    }
    if (plugin.adminUI && !plugin.routes?.admin) {
      result.warnings.push({
        code: "ADMIN_UI_NO_ROUTES",
        message: "Plugin has admin UI but no admin routes",
        suggestion: "Add admin routes to support the admin UI"
      });
    }
    if (plugin.services) {
      for (const [serviceName, service] of Object.entries(plugin.services)) {
        if (!service.class) {
          result.errors.push({
            code: "INVALID_SERVICE",
            message: `Service '${serviceName}' is missing class definition`,
            severity: "medium"
          });
        }
      }
    }
  }
  /**
   * Calculate overall plugin score
   */
  calculateScore(result) {
    let score = 100;
    for (const error of result.errors) {
      switch (error.severity) {
        case "critical":
          score -= 30;
          break;
        case "high":
          score -= 20;
          break;
        case "medium":
          score -= 10;
          break;
        case "low":
          score -= 5;
          break;
      }
    }
    score -= result.warnings.length * 2;
    return Math.max(0, score);
  }
  /**
   * Check if version range is valid
   */
  isValidVersionRange(version) {
    const semverPattern = /^[\^~]?\d+\.\d+\.\d+/;
    return semverPattern.test(version);
  }
  /**
   * Get validation recommendations
   */
  getRecommendations(result) {
    const recommendations = [];
    if (result.score < 70) {
      recommendations.push("Consider addressing validation errors and warnings to improve plugin quality");
    }
    if (result.errors.some((e) => e.severity === "critical")) {
      recommendations.push("Fix critical errors before publishing the plugin");
    }
    if (result.warnings.length > 5) {
      recommendations.push("Address warnings to improve plugin reliability and user experience");
    }
    return recommendations;
  }
};
async function validatePlugin(plugin, options) {
  const validator = new PluginValidator3(options);
  return await validator.validate(plugin);
}
var ValidationPresets = {
  // Strict validation for production plugins
  production: {
    strict: true,
    allowUnsafe: false,
    checkDependencies: true,
    validateCode: true,
    securityScan: true
  },
  // Relaxed validation for development
  development: {
    strict: false,
    allowUnsafe: true,
    checkDependencies: false,
    validateCode: true,
    securityScan: false
  },
  // Security-focused validation
  security: {
    strict: true,
    allowUnsafe: false,
    checkDependencies: true,
    validateCode: true,
    securityScan: true
  }
};

// src/plugins/plugin-sandbox-3.0.ts
var PluginSandbox3 = class {
  contexts = /* @__PURE__ */ new Map();
  violations = [];
  monitoringInterval = null;
  isMonitoring = false;
  constructor() {
  }
  /**
   * Create sandbox for plugin
   */
  createSandbox(pluginId, config) {
    const context = {
      pluginId,
      limits: {
        memory: 50 * 1024 * 1024,
        // 50MB default
        cpu: 5e3,
        // 5 seconds default
        networkRequests: 100,
        // per minute
        fileSystem: "plugin-directory",
        ...config.limits
      },
      allowedAPIs: new Set(config.allowedAPIs || this.getDefaultAllowedAPIs()),
      blockedAPIs: new Set(config.blockedAPIs || []),
      startTime: Date.now(),
      resourceUsage: {
        memory: 0,
        cpu: 0,
        networkRequests: 0,
        fileOperations: 0
      }
    };
    this.contexts.set(pluginId, context);
    if (!this.isMonitoring) {
      this.startMonitoring();
    }
    return context;
  }
  /**
   * Execute function in sandbox
   */
  async execute(pluginId, fn) {
    const context = this.contexts.get(pluginId);
    if (!context) {
      throw new Error(`No sandbox context found for plugin: ${pluginId}`);
    }
    this.checkResourceLimits(context);
    const startTime = Date.now();
    const startMemory = this.getCurrentMemoryUsage();
    try {
      this.createSandboxedGlobals(context);
      const result = await this.executeWithTimeout(fn, context.limits.cpu || 5e3);
      const endTime = Date.now();
      const endMemory = this.getCurrentMemoryUsage();
      context.resourceUsage.cpu += endTime - startTime;
      context.resourceUsage.memory = Math.max(context.resourceUsage.memory, endMemory - startMemory);
      return result;
    } catch (error) {
      this.recordViolation(context, "api", `Execution error: ${error}`, "error");
      throw error;
    }
  }
  /**
   * Check API access
   */
  checkAPIAccess(pluginId, apiName) {
    const context = this.contexts.get(pluginId);
    if (!context) return false;
    if (context.blockedAPIs.has(apiName)) {
      this.recordViolation(context, "api", `Blocked API access: ${apiName}`, "warning");
      return false;
    }
    if (context.allowedAPIs.size > 0 && !context.allowedAPIs.has(apiName)) {
      this.recordViolation(context, "api", `Unauthorized API access: ${apiName}`, "error");
      return false;
    }
    return true;
  }
  /**
   * Record network request
   */
  recordNetworkRequest(pluginId) {
    const context = this.contexts.get(pluginId);
    if (!context) return false;
    context.resourceUsage.networkRequests++;
    const requestsInLastMinute = this.getNetworkRequestsInWindow(context, 6e4);
    if (requestsInLastMinute > (context.limits.networkRequests || 100)) {
      this.recordViolation(context, "network", "Network request rate limit exceeded", "error");
      return false;
    }
    return true;
  }
  /**
   * Record file operation
   */
  recordFileOperation(pluginId, operation, path) {
    const context = this.contexts.get(pluginId);
    if (!context) return false;
    if (context.limits.fileSystem === "none") {
      this.recordViolation(context, "filesystem", `File system access denied: ${operation} ${path}`, "error");
      return false;
    }
    if (context.limits.fileSystem === "plugin-directory" && !this.isInPluginDirectory(pluginId, path)) {
      this.recordViolation(context, "filesystem", `File access outside plugin directory: ${path}`, "error");
      return false;
    }
    if (context.limits.fileSystem === "read-only" && operation === "write") {
      this.recordViolation(context, "filesystem", `Write operation denied in read-only mode: ${path}`, "error");
      return false;
    }
    context.resourceUsage.fileOperations++;
    return true;
  }
  /**
   * Get sandbox status
   */
  getSandboxStatus(pluginId) {
    const context = this.contexts.get(pluginId);
    if (!context) return null;
    const runtime = Date.now() - context.startTime;
    const violations = this.violations.filter((v) => v.pluginId === pluginId);
    return {
      pluginId,
      runtime,
      resourceUsage: { ...context.resourceUsage },
      limits: { ...context.limits },
      violations: violations.length,
      status: violations.some((v) => v.severity === "critical") ? "blocked" : violations.some((v) => v.severity === "error") ? "restricted" : "active"
    };
  }
  /**
   * Destroy sandbox
   */
  destroySandbox(pluginId) {
    this.contexts.delete(pluginId);
    this.violations = this.violations.filter((v) => v.pluginId !== pluginId);
  }
  /**
   * Get all violations
   */
  getViolations(pluginId) {
    if (pluginId) {
      return this.violations.filter((v) => v.pluginId === pluginId);
    }
    return [...this.violations];
  }
  getDefaultAllowedAPIs() {
    return [
      "console.log",
      "console.warn",
      "console.error",
      "JSON.parse",
      "JSON.stringify",
      "Date.now",
      "Math.*",
      "String.*",
      "Array.*",
      "Object.*"
    ];
  }
  createSandboxedGlobals(context) {
    const sandboxedConsole = {
      log: (...args) => {
        if (this.checkAPIAccess(context.pluginId, "console.log")) {
          console.log(`[${context.pluginId}]`, ...args);
        }
      },
      warn: (...args) => {
        if (this.checkAPIAccess(context.pluginId, "console.warn")) {
          console.warn(`[${context.pluginId}]`, ...args);
        }
      },
      error: (...args) => {
        if (this.checkAPIAccess(context.pluginId, "console.error")) {
          console.error(`[${context.pluginId}]`, ...args);
        }
      }
    };
    const sandboxedFetch = async (url, options) => {
      if (!this.recordNetworkRequest(context.pluginId)) {
        throw new Error("Network request denied");
      }
      if (!this.checkAPIAccess(context.pluginId, "fetch")) {
        throw new Error("Fetch API access denied");
      }
      return { ok: true, json: () => Promise.resolve({}) };
    };
    return {
      console: sandboxedConsole,
      fetch: sandboxedFetch,
      setTimeout: (fn, delay) => {
        if (this.checkAPIAccess(context.pluginId, "setTimeout")) {
          return setTimeout(fn, Math.min(delay, 3e4));
        }
        return 0;
      },
      setInterval: (fn, delay) => {
        if (this.checkAPIAccess(context.pluginId, "setInterval")) {
          return setInterval(fn, Math.max(delay, 1e3));
        }
        return 0;
      }
    };
  }
  async executeWithTimeout(fn, timeout) {
    return new Promise((resolve, reject) => {
      const timer = setTimeout(() => {
        reject(new Error("Execution timeout"));
      }, timeout);
      Promise.resolve(fn()).then((result) => {
        clearTimeout(timer);
        resolve(result);
      }).catch((error) => {
        clearTimeout(timer);
        reject(error);
      });
    });
  }
  checkResourceLimits(context) {
    if (context.limits.cpu && context.resourceUsage.cpu > context.limits.cpu) {
      this.recordViolation(context, "cpu", "CPU time limit exceeded", "critical");
      throw new Error("CPU time limit exceeded");
    }
    if (context.limits.memory && context.resourceUsage.memory > context.limits.memory) {
      this.recordViolation(context, "memory", "Memory limit exceeded", "critical");
      throw new Error("Memory limit exceeded");
    }
  }
  recordViolation(context, type, message, severity) {
    const violation = {
      type,
      message,
      pluginId: context.pluginId,
      timestamp: Date.now(),
      severity
    };
    this.violations.push(violation);
    if (this.violations.length > 1e3) {
      this.violations = this.violations.slice(-1e3);
    }
    if (severity === "critical") {
      console.error(`[Sandbox] Critical violation in ${context.pluginId}: ${message}`);
    }
  }
  getCurrentMemoryUsage() {
    try {
      if (typeof process !== "undefined" && process.memoryUsage) {
        return process.memoryUsage().heapUsed;
      }
    } catch {
    }
    return 0;
  }
  getNetworkRequestsInWindow(context, windowMs) {
    return context.resourceUsage.networkRequests;
  }
  isInPluginDirectory(pluginId, path) {
    return path.includes(`/plugins/${pluginId}/`) || path.startsWith(`./plugins/${pluginId}/`);
  }
  startMonitoring() {
    if (this.isMonitoring) return;
    this.isMonitoring = true;
    if (typeof setInterval !== "undefined") {
      this.monitoringInterval = setInterval(() => {
        this.monitorResourceUsage();
      }, 5e3);
    }
  }
  monitorResourceUsage() {
    for (const [pluginId, context] of this.contexts.entries()) {
      try {
        this.checkResourceLimits(context);
      } catch (error) {
      }
    }
  }
  /**
   * Cleanup resources
   */
  destroy() {
    if (this.monitoringInterval) {
      clearInterval(this.monitoringInterval);
      this.monitoringInterval = null;
    }
    this.isMonitoring = false;
    this.contexts.clear();
    this.violations = [];
  }
};
var pluginSandbox = new PluginSandbox3();

exports.AdminUIRegistry = AdminUIRegistry;
exports.HookSystem = HookSystem;
exports.HotReloadManager = HotReloadManager;
exports.PluginAPIUtils = PluginAPIUtils;
exports.PluginManager = PluginManager;
exports.PluginManifestSchema = PluginManifestSchema;
exports.PluginRegistry = PluginRegistry;
exports.PluginSandbox3 = PluginSandbox3;
exports.PluginValidator = PluginValidator;
exports.PluginValidator3 = PluginValidator3;
exports.RouteRegistry = RouteRegistry;
exports.STANDARD_HOOKS = STANDARD_HOOKS;
exports.ScopedHookSystem = ScopedHookSystem;
exports.ValidationPresets = ValidationPresets;
exports.createHotReloadMiddleware = createHotReloadMiddleware;
exports.createHotReloadRoutes = createHotReloadRoutes;
exports.createPlugin = createPlugin;
exports.pluginSandbox = pluginSandbox;
exports.resolvePluginLoadOrder = resolvePluginLoadOrder;
exports.validateDependencies = validateDependencies;
exports.validateManifest = validateManifest;
exports.validatePlugin = validatePlugin;
//# sourceMappingURL=chunk-UBSDXATH.cjs.map
//# sourceMappingURL=chunk-UBSDXATH.cjs.map