{"version":3,"file":"createSafeCapabilityRegistration.mjs","sources":["../../../../src/services/mcp/utils/createSafeCapabilityRegistration.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport type { RegisteredCapability } from '../internal/McpCapabilityRegistry';\nimport { wrapSafeHandler } from './safeHandlerWrapper';\n\n/**\n * A no-op registered capability used as fallback when SDK registration fails.\n *\n * This prevents one broken capability from aborting the entire registration loop.\n * The capability will appear as \"disabled\" and cannot be enabled.\n */\nexport const FAILED_REGISTERED_CAPABILITY: RegisteredCapability = Object.freeze({\n  enabled: false,\n  enable() {},\n  disable() {},\n  remove() {},\n});\n\n/**\n * Configuration for creating a safe capability registration\n */\nexport type SafeCapabilityRegistrationConfig<THandler, TErrorResult, TRegistered> = {\n  strapi: Core.Strapi;\n  capabilityType: string;\n  name: string;\n  createHandler: (strapi: Core.Strapi) => THandler;\n  createFallbackHandler: (errorMessage: string) => NoInfer<THandler>;\n  createErrorResult: (error: Error, args: unknown[]) => TErrorResult;\n  registerWithSdk: (safeHandler: THandler) => TRegistered;\n};\n\n/**\n * Creates a safe capability registration that protects Strapi core from user callback errors\n * at three levels:\n *\n * - Level 1: Catch factory invocation errors (createHandler throws)\n * - Level 2: Catch runtime execution errors (handler throws during invocation)\n * - Level 3: Catch MCP SDK registration errors (SDK rejects the registration)\n *\n * This prevents one broken capability from:\n * - Aborting the entire registration loop\n * - Crashing the MCP server\n * - Leaking unhandled errors to the user\n */\nexport const createSafeCapabilityRegistration = <THandler, TErrorResult, TRegistered>(\n  config: SafeCapabilityRegistrationConfig<THandler, TErrorResult, TRegistered>\n): TRegistered => {\n  const {\n    strapi,\n    capabilityType,\n    name,\n    createHandler,\n    createFallbackHandler,\n    createErrorResult,\n    registerWithSdk,\n  } = config;\n\n  try {\n    // Level 1: Safe factory invocation — catch errors from user's createHandler\n    let rawHandler: THandler;\n\n    try {\n      rawHandler = createHandler(strapi);\n    } catch (error) {\n      const message = error instanceof Error ? error.message : String(error);\n      strapi.log.error(\n        `[MCP] ${capabilityType} \"${name}\" handler factory threw during initialization: ${message}`\n      );\n\n      // Substitute a fallback handler that always returns an error to the MCP client\n      rawHandler = createFallbackHandler(message);\n    }\n\n    // Level 2: Safe runtime wrapping — catch errors from user's handler during execution\n    const safeHandler = wrapSafeHandler(rawHandler as (...args: unknown[]) => Promise<unknown>, {\n      strapi,\n      capabilityType,\n      name,\n      createErrorResult,\n    });\n\n    return registerWithSdk(safeHandler as THandler);\n  } catch (error) {\n    // Level 3: Catch MCP SDK registration errors — prevent one broken capability from aborting all others\n    const message = error instanceof Error ? error.message : String(error);\n    strapi.log.error(\n      `[MCP] Failed to register ${capabilityType.toLowerCase()} \"${name}\" with MCP server: ${message}`\n    );\n    return FAILED_REGISTERED_CAPABILITY as unknown as TRegistered;\n  }\n};\n"],"names":["FAILED_REGISTERED_CAPABILITY","Object","freeze","enabled","enable","disable","remove","createSafeCapabilityRegistration","config","strapi","capabilityType","name","createHandler","createFallbackHandler","createErrorResult","registerWithSdk","rawHandler","error","message","Error","String","log","safeHandler","wrapSafeHandler","toLowerCase"],"mappings":";;AAIA;;;;;AAKC,IACM,MAAMA,4BAAAA,GAAqDC,MAAAA,CAAOC,MAAM,CAAC;IAC9EC,OAAAA,EAAS,KAAA;IACTC,MAAAA,CAAAA,GAAAA,CAAU,CAAA;IACVC,OAAAA,CAAAA,GAAAA,CAAW,CAAA;IACXC,MAAAA,CAAAA,GAAAA,CAAU;AACZ,CAAA;AAeA;;;;;;;;;;;;IAaO,MAAMC,gCAAAA,GAAmC,CAC9CC,MAAAA,GAAAA;AAEA,IAAA,MAAM,EACJC,MAAM,EACNC,cAAc,EACdC,IAAI,EACJC,aAAa,EACbC,qBAAqB,EACrBC,iBAAiB,EACjBC,eAAe,EAChB,GAAGP,MAAAA;IAEJ,IAAI;;QAEF,IAAIQ,UAAAA;QAEJ,IAAI;AACFA,YAAAA,UAAAA,GAAaJ,aAAAA,CAAcH,MAAAA,CAAAA;AAC7B,QAAA,CAAA,CAAE,OAAOQ,KAAAA,EAAO;AACd,YAAA,MAAMC,UAAUD,KAAAA,YAAiBE,KAAAA,GAAQF,KAAAA,CAAMC,OAAO,GAAGE,MAAAA,CAAOH,KAAAA,CAAAA;AAChER,YAAAA,MAAAA,CAAOY,GAAG,CAACJ,KAAK,CACd,CAAC,MAAM,EAAEP,cAAAA,CAAe,EAAE,EAAEC,IAAAA,CAAK,+CAA+C,EAAEO,OAAAA,CAAAA,CAAS,CAAA;;AAI7FF,YAAAA,UAAAA,GAAaH,qBAAAA,CAAsBK,OAAAA,CAAAA;AACrC,QAAA;;QAGA,MAAMI,WAAAA,GAAcC,gBAAgBP,UAAAA,EAAwD;AAC1FP,YAAAA,MAAAA;AACAC,YAAAA,cAAAA;AACAC,YAAAA,IAAAA;AACAG,YAAAA;AACF,SAAA,CAAA;AAEA,QAAA,OAAOC,eAAAA,CAAgBO,WAAAA,CAAAA;AACzB,IAAA,CAAA,CAAE,OAAOL,KAAAA,EAAO;;AAEd,QAAA,MAAMC,UAAUD,KAAAA,YAAiBE,KAAAA,GAAQF,KAAAA,CAAMC,OAAO,GAAGE,MAAAA,CAAOH,KAAAA,CAAAA;AAChER,QAAAA,MAAAA,CAAOY,GAAG,CAACJ,KAAK,CACd,CAAC,yBAAyB,EAAEP,cAAAA,CAAec,WAAW,GAAG,EAAE,EAAEb,IAAAA,CAAK,mBAAmB,EAAEO,OAAAA,CAAAA,CAAS,CAAA;QAElG,OAAOlB,4BAAAA;AACT,IAAA;AACF;;;;"}