@frontmcp/sdk 0.5.1 → 0.6.1

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 (265) hide show
  1. package/README.md +1 -0
  2. package/package.json +12 -16
  3. package/src/adapter/adapter.instance.js +5 -0
  4. package/src/adapter/adapter.instance.js.map +1 -1
  5. package/src/auth/authorization/authorization.class.d.ts +1 -4
  6. package/src/auth/authorization/authorization.class.js +6 -13
  7. package/src/auth/authorization/authorization.class.js.map +1 -1
  8. package/src/auth/flows/session.verify.flow.d.ts +1 -0
  9. package/src/auth/flows/session.verify.flow.js +11 -1
  10. package/src/auth/flows/session.verify.flow.js.map +1 -1
  11. package/src/auth/flows/well-known.jwks.flow.js +2 -2
  12. package/src/auth/flows/well-known.jwks.flow.js.map +1 -1
  13. package/src/auth/jwks/dev-key-persistence.d.ts +63 -0
  14. package/src/auth/jwks/dev-key-persistence.js +219 -0
  15. package/src/auth/jwks/dev-key-persistence.js.map +1 -0
  16. package/src/auth/jwks/index.d.ts +1 -0
  17. package/src/auth/jwks/index.js +1 -0
  18. package/src/auth/jwks/index.js.map +1 -1
  19. package/src/auth/jwks/jwks.service.d.ts +7 -4
  20. package/src/auth/jwks/jwks.service.js +81 -12
  21. package/src/auth/jwks/jwks.service.js.map +1 -1
  22. package/src/auth/jwks/jwks.types.d.ts +7 -0
  23. package/src/auth/jwks/jwks.types.js.map +1 -1
  24. package/src/auth/machine-id.d.ts +5 -0
  25. package/src/auth/machine-id.js +32 -0
  26. package/src/auth/machine-id.js.map +1 -0
  27. package/src/auth/session/index.d.ts +2 -0
  28. package/src/auth/session/index.js +5 -1
  29. package/src/auth/session/index.js.map +1 -1
  30. package/src/auth/session/record/session.base.js +5 -3
  31. package/src/auth/session/record/session.base.js.map +1 -1
  32. package/src/auth/session/record/session.stateless.d.ts +2 -2
  33. package/src/auth/session/record/session.stateless.js +5 -3
  34. package/src/auth/session/record/session.stateless.js.map +1 -1
  35. package/src/auth/session/redis-session.store.d.ts +64 -0
  36. package/src/auth/session/redis-session.store.js +204 -0
  37. package/src/auth/session/redis-session.store.js.map +1 -0
  38. package/src/auth/session/session.service.d.ts +0 -2
  39. package/src/auth/session/session.service.js +1 -7
  40. package/src/auth/session/session.service.js.map +1 -1
  41. package/src/auth/session/transport-session.manager.js +3 -5
  42. package/src/auth/session/transport-session.manager.js.map +1 -1
  43. package/src/auth/session/transport-session.types.d.ts +4 -0
  44. package/src/auth/session/transport-session.types.js +4 -3
  45. package/src/auth/session/transport-session.types.js.map +1 -1
  46. package/src/auth/session/utils/session-id.utils.d.ts +12 -1
  47. package/src/auth/session/utils/session-id.utils.js +48 -9
  48. package/src/auth/session/utils/session-id.utils.js.map +1 -1
  49. package/src/auth/session/vercel-kv-session.store.d.ts +96 -0
  50. package/src/auth/session/vercel-kv-session.store.js +216 -0
  51. package/src/auth/session/vercel-kv-session.store.js.map +1 -0
  52. package/src/auth/ui/base-layout.d.ts +0 -8
  53. package/src/auth/ui/base-layout.js +1 -14
  54. package/src/auth/ui/base-layout.js.map +1 -1
  55. package/src/auth/ui/index.d.ts +3 -4
  56. package/src/auth/ui/index.js +10 -11
  57. package/src/auth/ui/index.js.map +1 -1
  58. package/src/auth/ui/{htmx-templates.d.ts → templates.d.ts} +5 -6
  59. package/src/auth/ui/{htmx-templates.js → templates.js} +8 -15
  60. package/src/auth/ui/templates.js.map +1 -0
  61. package/src/common/decorators/decorator-utils.js.map +1 -1
  62. package/src/common/decorators/front-mcp.decorator.js +26 -3
  63. package/src/common/decorators/front-mcp.decorator.js.map +1 -1
  64. package/src/common/index.d.ts +0 -1
  65. package/src/common/index.js +0 -1
  66. package/src/common/index.js.map +1 -1
  67. package/src/common/interfaces/adapter.interface.d.ts +6 -0
  68. package/src/common/interfaces/adapter.interface.js.map +1 -1
  69. package/src/common/interfaces/execution-context.interface.d.ts +52 -3
  70. package/src/common/interfaces/execution-context.interface.js +88 -3
  71. package/src/common/interfaces/execution-context.interface.js.map +1 -1
  72. package/src/common/interfaces/flow.interface.d.ts +13 -0
  73. package/src/common/interfaces/flow.interface.js +24 -0
  74. package/src/common/interfaces/flow.interface.js.map +1 -1
  75. package/src/common/interfaces/server.interface.d.ts +9 -0
  76. package/src/common/interfaces/server.interface.js.map +1 -1
  77. package/src/common/metadata/app.metadata.d.ts +108 -0
  78. package/src/common/metadata/front-mcp.metadata.d.ts +1341 -2
  79. package/src/common/metadata/front-mcp.metadata.js +4 -1
  80. package/src/common/metadata/front-mcp.metadata.js.map +1 -1
  81. package/src/common/metadata/prompt.metadata.d.ts +4 -0
  82. package/src/common/metadata/provider.metadata.d.ts +14 -0
  83. package/src/common/metadata/provider.metadata.js +18 -2
  84. package/src/common/metadata/provider.metadata.js.map +1 -1
  85. package/src/common/metadata/resource.metadata.d.ts +8 -0
  86. package/src/common/metadata/tool-ui.metadata.d.ts +2 -2
  87. package/src/common/metadata/tool-ui.metadata.js +1 -1
  88. package/src/common/metadata/tool-ui.metadata.js.map +1 -1
  89. package/src/common/metadata/tool.metadata.d.ts +5 -1
  90. package/src/common/metadata/tool.metadata.js.map +1 -1
  91. package/src/common/migrate/auth-transport.migrate.d.ts +62 -0
  92. package/src/common/migrate/auth-transport.migrate.js +140 -0
  93. package/src/common/migrate/auth-transport.migrate.js.map +1 -0
  94. package/src/common/migrate/index.d.ts +1 -0
  95. package/src/common/migrate/index.js +6 -0
  96. package/src/common/migrate/index.js.map +1 -0
  97. package/src/common/schemas/http-output.schema.d.ts +24 -6
  98. package/src/common/schemas/index.d.ts +1 -0
  99. package/src/common/schemas/index.js +1 -0
  100. package/src/common/schemas/index.js.map +1 -1
  101. package/src/common/schemas/session-header.schema.d.ts +16 -0
  102. package/src/common/schemas/session-header.schema.js +42 -0
  103. package/src/common/schemas/session-header.schema.js.map +1 -0
  104. package/src/common/tokens/front-mcp.tokens.js +4 -1
  105. package/src/common/tokens/front-mcp.tokens.js.map +1 -1
  106. package/src/common/types/options/auth.options.d.ts +233 -3
  107. package/src/common/types/options/auth.options.js +29 -40
  108. package/src/common/types/options/auth.options.js.map +1 -1
  109. package/src/common/types/options/index.d.ts +2 -0
  110. package/src/common/types/options/index.js +2 -0
  111. package/src/common/types/options/index.js.map +1 -1
  112. package/src/common/types/options/redis.options.d.ts +190 -0
  113. package/src/common/types/options/redis.options.js +191 -0
  114. package/src/common/types/options/redis.options.js.map +1 -0
  115. package/src/common/types/options/server-info.options.d.ts +4 -0
  116. package/src/common/types/options/transport.options.d.ts +148 -0
  117. package/src/common/types/options/transport.options.js +121 -0
  118. package/src/common/types/options/transport.options.js.map +1 -0
  119. package/src/common/utils/global-config.utils.d.ts +36 -0
  120. package/src/common/utils/global-config.utils.js +44 -0
  121. package/src/common/utils/global-config.utils.js.map +1 -0
  122. package/src/common/utils/index.d.ts +1 -0
  123. package/src/common/utils/index.js +1 -0
  124. package/src/common/utils/index.js.map +1 -1
  125. package/src/completion/flows/complete.flow.d.ts +6 -8
  126. package/src/context/frontmcp-context-storage.d.ts +94 -0
  127. package/src/context/frontmcp-context-storage.js +183 -0
  128. package/src/context/frontmcp-context-storage.js.map +1 -0
  129. package/src/context/frontmcp-context.d.ts +269 -0
  130. package/src/context/frontmcp-context.js +360 -0
  131. package/src/context/frontmcp-context.js.map +1 -0
  132. package/src/context/frontmcp-context.provider.d.ts +43 -0
  133. package/src/context/frontmcp-context.provider.js +61 -0
  134. package/src/context/frontmcp-context.provider.js.map +1 -0
  135. package/src/context/index.d.ts +34 -0
  136. package/src/context/index.js +64 -0
  137. package/src/context/index.js.map +1 -0
  138. package/src/context/request-context-storage.d.ts +89 -0
  139. package/src/context/request-context-storage.js +183 -0
  140. package/src/context/request-context-storage.js.map +1 -0
  141. package/src/context/request-context.d.ts +184 -0
  142. package/src/context/request-context.js +209 -0
  143. package/src/context/request-context.js.map +1 -0
  144. package/src/context/request-context.provider.d.ts +37 -0
  145. package/src/context/request-context.provider.js +51 -0
  146. package/src/context/request-context.provider.js.map +1 -0
  147. package/src/context/session-key.provider.d.ts +45 -0
  148. package/src/context/session-key.provider.js +65 -0
  149. package/src/context/session-key.provider.js.map +1 -0
  150. package/src/context/trace-context.d.ts +43 -0
  151. package/src/context/trace-context.js +142 -0
  152. package/src/context/trace-context.js.map +1 -0
  153. package/src/errors/index.d.ts +1 -1
  154. package/src/errors/index.js +4 -1
  155. package/src/errors/index.js.map +1 -1
  156. package/src/errors/mcp.error.d.ts +16 -0
  157. package/src/errors/mcp.error.js +29 -1
  158. package/src/errors/mcp.error.js.map +1 -1
  159. package/src/flows/flow.instance.d.ts +16 -0
  160. package/src/flows/flow.instance.js +166 -80
  161. package/src/flows/flow.instance.js.map +1 -1
  162. package/src/flows/flow.registry.d.ts +5 -0
  163. package/src/flows/flow.registry.js +45 -3
  164. package/src/flows/flow.registry.js.map +1 -1
  165. package/src/front-mcp/front-mcp.d.ts +12 -0
  166. package/src/front-mcp/front-mcp.js +22 -3
  167. package/src/front-mcp/front-mcp.js.map +1 -1
  168. package/src/front-mcp/front-mcp.providers.d.ts +474 -1
  169. package/src/front-mcp/front-mcp.providers.js +2 -1
  170. package/src/front-mcp/front-mcp.providers.js.map +1 -1
  171. package/src/front-mcp/index.d.ts +1 -0
  172. package/src/front-mcp/index.js +3 -0
  173. package/src/front-mcp/index.js.map +1 -1
  174. package/src/front-mcp/serverless-handler.d.ts +28 -0
  175. package/src/front-mcp/serverless-handler.js +61 -0
  176. package/src/front-mcp/serverless-handler.js.map +1 -0
  177. package/src/hooks/hooks.utils.d.ts +1 -1
  178. package/src/hooks/hooks.utils.js +10 -3
  179. package/src/hooks/hooks.utils.js.map +1 -1
  180. package/src/index.d.ts +9 -5
  181. package/src/index.js +21 -1
  182. package/src/index.js.map +1 -1
  183. package/src/logger/instances/instance.logger.js +0 -1
  184. package/src/logger/instances/instance.logger.js.map +1 -1
  185. package/src/logging/flows/set-level.flow.d.ts +6 -8
  186. package/src/notification/notification.service.js +5 -1
  187. package/src/notification/notification.service.js.map +1 -1
  188. package/src/prompt/flows/get-prompt.flow.d.ts +14 -8
  189. package/src/prompt/flows/prompts-list.flow.d.ts +8 -7
  190. package/src/provider/provider.registry.d.ts +97 -5
  191. package/src/provider/provider.registry.js +306 -9
  192. package/src/provider/provider.registry.js.map +1 -1
  193. package/src/provider/provider.types.d.ts +21 -3
  194. package/src/provider/provider.types.js.map +1 -1
  195. package/src/resource/flows/read-resource.flow.d.ts +8 -9
  196. package/src/resource/flows/resource-templates-list.flow.d.ts +8 -7
  197. package/src/resource/flows/resources-list.flow.d.ts +8 -7
  198. package/src/resource/flows/subscribe-resource.flow.d.ts +6 -8
  199. package/src/resource/flows/unsubscribe-resource.flow.d.ts +6 -8
  200. package/src/scope/flows/http.request.flow.js +43 -7
  201. package/src/scope/flows/http.request.flow.js.map +1 -1
  202. package/src/scope/scope.instance.js +12 -5
  203. package/src/scope/scope.instance.js.map +1 -1
  204. package/src/server/adapters/base.host.adapter.d.ts +9 -0
  205. package/src/server/adapters/base.host.adapter.js.map +1 -1
  206. package/src/server/adapters/express.host.adapter.d.ts +12 -0
  207. package/src/server/adapters/express.host.adapter.js +21 -1
  208. package/src/server/adapters/express.host.adapter.js.map +1 -1
  209. package/src/server/server.instance.d.ts +3 -0
  210. package/src/server/server.instance.js +14 -7
  211. package/src/server/server.instance.js.map +1 -1
  212. package/src/store/adapters/store.vercel-kv.adapter.d.ts +86 -0
  213. package/src/store/adapters/store.vercel-kv.adapter.js +155 -0
  214. package/src/store/adapters/store.vercel-kv.adapter.js.map +1 -0
  215. package/src/store/index.d.ts +2 -0
  216. package/src/store/index.js +2 -0
  217. package/src/store/index.js.map +1 -1
  218. package/src/store/store.factory.d.ts +86 -0
  219. package/src/store/store.factory.js +194 -0
  220. package/src/store/store.factory.js.map +1 -0
  221. package/src/tool/flows/call-tool.flow.d.ts +38 -19
  222. package/src/tool/flows/call-tool.flow.js +240 -194
  223. package/src/tool/flows/call-tool.flow.js.map +1 -1
  224. package/src/tool/flows/tools-list.flow.d.ts +14 -17
  225. package/src/tool/flows/tools-list.flow.js +84 -33
  226. package/src/tool/flows/tools-list.flow.js.map +1 -1
  227. package/src/tool/tool.instance.d.ts +1 -4
  228. package/src/tool/ui/index.d.ts +4 -4
  229. package/src/tool/ui/index.js +4 -4
  230. package/src/tool/ui/index.js.map +1 -1
  231. package/src/tool/ui/platform-adapters.d.ts +2 -2
  232. package/src/tool/ui/platform-adapters.js +3 -3
  233. package/src/tool/ui/platform-adapters.js.map +1 -1
  234. package/src/tool/ui/template-helpers.d.ts +5 -7
  235. package/src/tool/ui/template-helpers.js +9 -26
  236. package/src/tool/ui/template-helpers.js.map +1 -1
  237. package/src/tool/ui/ui-resource.handler.d.ts +1 -1
  238. package/src/tool/ui/ui-resource.handler.js +5 -5
  239. package/src/tool/ui/ui-resource.handler.js.map +1 -1
  240. package/src/transport/adapters/transport.streamable-http.adapter.js +1 -0
  241. package/src/transport/adapters/transport.streamable-http.adapter.js.map +1 -1
  242. package/src/transport/flows/handle.sse.flow.js +9 -2
  243. package/src/transport/flows/handle.sse.flow.js.map +1 -1
  244. package/src/transport/flows/handle.streamable-http.flow.js +63 -6
  245. package/src/transport/flows/handle.streamable-http.flow.js.map +1 -1
  246. package/src/transport/mcp-handlers/complete-request.handler.d.ts +4 -15
  247. package/src/transport/mcp-handlers/get-prompt-request.handler.d.ts +5 -15
  248. package/src/transport/mcp-handlers/index.d.ts +67 -195
  249. package/src/transport/mcp-handlers/initialize-request.handler.js +12 -2
  250. package/src/transport/mcp-handlers/initialize-request.handler.js.map +1 -1
  251. package/src/transport/mcp-handlers/list-prompts-request.handler.d.ts +5 -15
  252. package/src/transport/mcp-handlers/list-resource-templates-request.handler.d.ts +5 -15
  253. package/src/transport/mcp-handlers/list-resources-request.handler.d.ts +5 -15
  254. package/src/transport/mcp-handlers/list-tools-request.handler.d.ts +5 -15
  255. package/src/transport/mcp-handlers/logging-set-level-request.handler.d.ts +3 -14
  256. package/src/transport/mcp-handlers/read-resource-request.handler.d.ts +4 -15
  257. package/src/transport/mcp-handlers/subscribe-request.handler.d.ts +3 -14
  258. package/src/transport/mcp-handlers/unsubscribe-request.handler.d.ts +3 -14
  259. package/src/transport/transport.registry.d.ts +72 -4
  260. package/src/transport/transport.registry.js +342 -11
  261. package/src/transport/transport.registry.js.map +1 -1
  262. package/src/auth/ui/htmx-templates.js.map +0 -1
  263. package/src/common/providers/session.provider.d.ts +0 -13
  264. package/src/common/providers/session.provider.js +0 -27
  265. package/src/common/providers/session.provider.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../../src/auth/ui/templates.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Template Builders for OAuth UI\n *\n * Server-side HTML rendering with Tailwind CSS for OAuth authorization flows.\n * No build step required - pure runtime rendering with Tailwind CSS CDN.\n *\n * Features:\n * - OAuth consent page with multiple apps\n * - Incremental authorization page for single app\n * - Federated login page for multi-provider selection\n * - All pages use Tailwind CSS from CDN (no build required)\n * - Google Fonts (Inter) for modern typography\n *\n * Uses base-layout.ts for consistent HTML shell with CDN resources.\n */\n\nimport {\n baseLayout,\n wideLayout,\n extraWideLayout,\n centeredCardLayout,\n escapeHtml as baseEscapeHtml,\n} from './base-layout';\n\n// ============================================\n// Types\n// ============================================\n\n/**\n * App information for authorization cards\n */\nexport interface AppAuthCard {\n /** App identifier */\n appId: string;\n /** Display name */\n appName: string;\n /** App description */\n description?: string;\n /** Icon URL (optional, will use initials fallback) */\n iconUrl?: string;\n /** Scopes required by this app */\n requiredScopes?: string[];\n}\n\n/**\n * Provider information for federated login\n */\nexport interface ProviderCard {\n /** Provider identifier */\n providerId: string;\n /** Display name */\n providerName: string;\n /** Provider URL (for remote providers) */\n providerUrl?: string;\n /** Auth mode */\n mode: string;\n /** App IDs associated with this provider */\n appIds: string[];\n /** Whether this is the parent/primary provider */\n isPrimary?: boolean;\n}\n\n/**\n * Tool information for consent page\n */\nexport interface ToolCard {\n /** Tool identifier */\n toolId: string;\n /** Display name */\n toolName: string;\n /** Tool description */\n description?: string;\n /** Parent app ID */\n appId: string;\n /** Parent app name */\n appName: string;\n}\n\n// ============================================\n// Utility Functions\n// ============================================\n\n/**\n * Escape HTML special characters\n * Re-exported from base-layout for convenience\n */\nexport const escapeHtml = baseEscapeHtml;\n\n// ============================================\n// Template Builders\n// ============================================\n\n/**\n * Build OAuth consent page with Tailwind\n * Shows all apps at once with Authorize/Skip buttons\n */\nexport function buildConsentPage(params: {\n apps: AppAuthCard[];\n clientName: string;\n pendingAuthId: string;\n csrfToken: string;\n callbackPath: string;\n}): string {\n const { apps, clientName, pendingAuthId, csrfToken, callbackPath } = params;\n\n const appCards = apps.map((app) => buildAppCardHtml(app, pendingAuthId, csrfToken, callbackPath)).join('\\n');\n\n const content = `\n <h1 class=\"text-3xl font-bold text-gray-900 mb-4\">Authorize ${escapeHtml(clientName)}</h1>\n <p class=\"text-gray-600 mb-8\">\n Select which apps you want to authorize. You can skip apps and authorize them later when needed.\n </p>\n\n <div class=\"space-y-4\" id=\"app-list\">\n ${appCards}\n </div>\n\n <div class=\"mt-6 p-4 bg-blue-50 border border-blue-200 rounded-lg text-sm text-blue-800\">\n Skipped apps can be authorized later when you try to use their tools (progressive authorization).\n </div>`;\n\n return wideLayout(content, { title: `Authorize ${clientName}` });\n}\n\n/**\n * Build single app authorization card HTML\n */\nfunction buildAppCardHtml(app: AppAuthCard, pendingAuthId: string, csrfToken: string, callbackPath: string): string {\n const icon = app.iconUrl\n ? `<img src=\"${escapeHtml(app.iconUrl)}\" alt=\"${escapeHtml(\n app.appName,\n )}\" class=\"w-12 h-12 rounded-lg object-cover\">`\n : `<div class=\"w-12 h-12 rounded-lg bg-gradient-to-br from-blue-500 to-purple-600 flex items-center justify-center text-white font-bold text-lg\">${escapeHtml(\n app.appName.charAt(0).toUpperCase(),\n )}</div>`;\n\n const description = app.description ? `<p class=\"text-sm text-gray-500\">${escapeHtml(app.description)}</p>` : '';\n\n const scopes = app.requiredScopes?.length\n ? `<div class=\"mb-4\">\n <p class=\"text-xs font-medium text-gray-500 uppercase tracking-wide mb-2\">Permissions</p>\n <div class=\"flex flex-wrap gap-2\">\n ${app.requiredScopes\n .map(\n (scope) =>\n `<span class=\"inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800\">${escapeHtml(\n scope,\n )}</span>`,\n )\n .join('')}\n </div>\n </div>`\n : '';\n\n return `<div class=\"bg-white rounded-xl shadow-sm border border-gray-200 p-6 hover:shadow-md transition-shadow\" data-app-id=\"${escapeHtml(\n app.appId,\n )}\">\n <div class=\"flex items-center gap-4 mb-4\">\n ${icon}\n <div class=\"flex-1\">\n <h3 class=\"font-semibold text-gray-900\">${escapeHtml(app.appName)}</h3>\n ${description}\n </div>\n </div>\n\n ${scopes}\n\n <form method=\"POST\" action=\"${escapeHtml(callbackPath)}\" class=\"flex gap-3 pt-4 border-t border-gray-100\">\n <input type=\"hidden\" name=\"csrf\" value=\"${escapeHtml(csrfToken)}\">\n <input type=\"hidden\" name=\"pending_auth_id\" value=\"${escapeHtml(pendingAuthId)}\">\n <input type=\"hidden\" name=\"app\" value=\"${escapeHtml(app.appId)}\">\n <button type=\"submit\" name=\"action\" value=\"authorize\"\n class=\"flex-1 bg-blue-600 hover:bg-blue-700 text-white font-medium py-2.5 px-4 rounded-lg transition-colors\">\n Authorize\n </button>\n <button type=\"submit\" name=\"action\" value=\"skip\"\n class=\"px-4 py-2.5 text-gray-600 hover:text-gray-900 hover:bg-gray-100 font-medium rounded-lg transition-colors\">\n Skip\n </button>\n </form>\n </div>`;\n}\n\n/**\n * Build incremental auth page (single app) with Tailwind\n * Used when a tool requires authorization for a skipped app\n */\nexport function buildIncrementalAuthPage(params: {\n app: AppAuthCard;\n toolId: string;\n sessionHint: string;\n callbackPath: string;\n}): string {\n const { app, toolId, sessionHint, callbackPath } = params;\n\n const description = app.description ? `<p class=\"text-gray-500 mt-2\">${escapeHtml(app.description)}</p>` : '';\n\n const content = `\n <!-- Warning icon -->\n <div class=\"flex justify-center mb-6\">\n <div class=\"w-16 h-16 rounded-full bg-amber-100 flex items-center justify-center\">\n <svg class=\"w-8 h-8 text-amber-600\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"/>\n </svg>\n </div>\n </div>\n\n <h1 class=\"text-2xl font-bold text-gray-900 text-center mb-2\">Authorization Required</h1>\n <p class=\"text-gray-600 text-center mb-8\">\n To use \"<span class=\"font-mono text-sm bg-gray-100 px-1 rounded\">${escapeHtml(\n toolId,\n )}</span>\", you need to authorize ${escapeHtml(app.appName)}.\n </p>\n\n <!-- App card -->\n <div class=\"bg-white rounded-xl shadow-sm border border-gray-200 p-6 mb-6\">\n <div class=\"flex items-center gap-4 mb-4\">\n <div class=\"w-12 h-12 rounded-lg bg-gradient-to-br from-blue-500 to-purple-600 flex items-center justify-center text-white font-bold text-lg\">\n ${escapeHtml(app.appName.charAt(0).toUpperCase())}\n </div>\n <div class=\"flex-1\">\n <h3 class=\"font-semibold text-gray-900\">${escapeHtml(app.appName)}</h3>\n ${description}\n </div>\n </div>\n\n <form method=\"GET\" action=\"${escapeHtml(callbackPath)}\" class=\"flex gap-3 pt-4 border-t border-gray-100\">\n <input type=\"hidden\" name=\"pending_auth_id\" value=\"${escapeHtml(sessionHint)}\">\n <input type=\"hidden\" name=\"app_id\" value=\"${escapeHtml(app.appId)}\">\n <input type=\"hidden\" name=\"incremental\" value=\"true\">\n <button type=\"button\" onclick=\"window.close()\"\n class=\"flex-1 px-4 py-2.5 text-gray-600 hover:text-gray-900 hover:bg-gray-100 font-medium rounded-lg transition-colors\">\n Cancel\n </button>\n <button type=\"submit\"\n class=\"flex-1 bg-blue-600 hover:bg-blue-700 text-white font-medium py-2.5 px-4 rounded-lg transition-colors\">\n Authorize\n </button>\n </form>\n </div>\n\n <div class=\"p-4 bg-amber-50 border border-amber-200 rounded-lg text-sm text-amber-800 text-center\">\n This is an incremental authorization. Your existing session will be expanded to include ${escapeHtml(\n app.appName,\n )}.\n </div>`;\n\n return centeredCardLayout(content, { title: `Authorize ${app.appName}` });\n}\n\n/**\n * Build federated login page for multi-provider selection\n */\nexport function buildFederatedLoginPage(params: {\n providers: ProviderCard[];\n clientName: string;\n pendingAuthId: string;\n csrfToken: string;\n callbackPath: string;\n}): string {\n const { providers, clientName, pendingAuthId, csrfToken, callbackPath } = params;\n\n const providerCards = providers\n .map((provider) => {\n const isPrimaryBadge = provider.isPrimary\n ? `<span class=\"px-2 py-0.5 text-xs font-medium bg-blue-600 text-white rounded-full\">Primary</span>`\n : '';\n\n const providerUrl = provider.providerUrl\n ? `<p class=\"text-xs text-gray-400 font-mono truncate\">${escapeHtml(provider.providerUrl)}</p>`\n : '';\n\n const appIds =\n provider.appIds.length > 0\n ? `<p class=\"text-xs text-gray-500 mt-1\">Apps: ${provider.appIds.map((id) => escapeHtml(id)).join(', ')}</p>`\n : '';\n\n return `<label class=\"flex items-start gap-4 p-4 bg-white border-2 border-gray-200 rounded-xl cursor-pointer hover:border-blue-300 transition-colors has-[:checked]:border-blue-500 has-[:checked]:bg-blue-50\">\n <input type=\"checkbox\" name=\"providers\" value=\"${escapeHtml(provider.providerId)}\"\n class=\"mt-1 w-5 h-5 rounded border-gray-300\" ${provider.isPrimary ? 'checked' : ''}>\n <div class=\"flex-1\">\n <div class=\"flex items-center gap-2 mb-1\">\n <span class=\"font-semibold text-gray-900\">${escapeHtml(provider.providerName)}</span>\n ${isPrimaryBadge}\n </div>\n <p class=\"text-sm text-gray-500\">Mode: ${escapeHtml(provider.mode)}</p>\n ${providerUrl}\n ${appIds}\n </div>\n </label>`;\n })\n .join('\\n');\n\n const content = `\n <h1 class=\"text-3xl font-bold text-gray-900 mb-4\">Select Authorization Providers</h1>\n <p class=\"text-gray-600 mb-8\">\n ${escapeHtml(clientName)} uses multiple authentication providers. Select which ones you want to authorize.\n </p>\n\n <form method=\"GET\" action=\"${escapeHtml(callbackPath)}\" id=\"federated-form\">\n <input type=\"hidden\" name=\"pending_auth_id\" value=\"${escapeHtml(pendingAuthId)}\">\n <input type=\"hidden\" name=\"federated\" value=\"true\">\n\n <!-- Select all toggle -->\n <label class=\"flex items-center gap-3 mb-6 cursor-pointer\">\n <input type=\"checkbox\" id=\"select-all\" class=\"w-5 h-5 rounded border-gray-300\"\n onchange=\"document.querySelectorAll('input[name=providers]').forEach(cb => cb.checked = this.checked)\">\n <span class=\"text-gray-700\">Select all providers</span>\n </label>\n\n <!-- Provider cards -->\n <div class=\"space-y-4 mb-8\">\n ${providerCards}\n </div>\n\n <!-- Email input -->\n <div class=\"mb-6\">\n <label for=\"email\" class=\"block text-sm font-medium text-gray-700 mb-2\">Email</label>\n <input type=\"email\" id=\"email\" name=\"email\" required placeholder=\"you@example.com\"\n class=\"w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500\">\n </div>\n\n <!-- Buttons -->\n <div class=\"flex gap-4\">\n <button type=\"button\"\n class=\"flex-1 px-6 py-3 text-gray-700 bg-gray-100 hover:bg-gray-200 font-medium rounded-lg transition-colors\"\n onclick=\"document.querySelectorAll('input[name=providers]').forEach(cb => cb.checked = false); document.getElementById('federated-form').submit();\">\n Skip All\n </button>\n <button type=\"submit\"\n class=\"flex-1 px-6 py-3 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-lg transition-colors\">\n Continue\n </button>\n </div>\n </form>\n\n <div class=\"mt-6 p-4 bg-blue-50 border border-blue-200 rounded-lg text-sm text-blue-800\">\n Skipped providers can be authorized later when you try to use their tools (progressive authorization).\n </div>`;\n\n return wideLayout(content, { title: 'Select Providers' });\n}\n\n/**\n * Build consent page for tool selection\n */\nexport function buildToolConsentPage(params: {\n tools: ToolCard[];\n clientName: string;\n pendingAuthId: string;\n csrfToken: string;\n callbackPath: string;\n userName?: string;\n userEmail?: string;\n}): string {\n const { tools, clientName, pendingAuthId, csrfToken, callbackPath, userName, userEmail } = params;\n\n // Group tools by app\n const toolsByApp: Record<string, { appName: string; tools: ToolCard[] }> = {};\n for (const tool of tools) {\n if (!toolsByApp[tool.appId]) {\n toolsByApp[tool.appId] = { appName: tool.appName, tools: [] };\n }\n toolsByApp[tool.appId].tools.push(tool);\n }\n\n const userInfo =\n userName || userEmail\n ? `<div class=\"p-3 bg-gray-50 rounded-lg mb-6 text-sm\">\n <span class=\"text-gray-500\">Signed in as: </span>\n <span class=\"font-medium text-gray-900\">${escapeHtml(userName || userEmail || '')}</span>\n </div>`\n : '';\n\n const appGroups = Object.entries(toolsByApp)\n .map(([appId, { appName, tools: appTools }]) => {\n const toolItems = appTools\n .map((tool) => {\n const desc = tool.description\n ? `<p class=\"text-sm text-gray-500 mt-0.5\">${escapeHtml(tool.description)}</p>`\n : '';\n return `<label class=\"flex items-start gap-3 p-3 bg-white rounded-lg cursor-pointer hover:bg-gray-50\">\n <input type=\"checkbox\" name=\"tools\" value=\"${escapeHtml(\n tool.toolId,\n )}\" class=\"mt-0.5 w-5 h-5 rounded border-gray-300\" checked>\n <div>\n <span class=\"font-medium text-gray-900\">${escapeHtml(tool.toolName)}</span>\n ${desc}\n </div>\n </label>`;\n })\n .join('\\n');\n\n return `<div class=\"bg-gray-50 rounded-xl overflow-hidden\">\n <div class=\"flex items-center justify-between px-4 py-3 bg-gray-100\">\n <div class=\"flex items-center gap-3\">\n <div class=\"w-8 h-8 rounded-lg bg-gradient-to-br from-blue-500 to-purple-600 flex items-center justify-center text-white font-bold text-sm\">\n ${escapeHtml(appName.charAt(0).toUpperCase())}\n </div>\n <span class=\"font-semibold text-gray-900\">${escapeHtml(appName)}</span>\n </div>\n <button type=\"button\" class=\"text-sm text-blue-600 hover:text-blue-800\"\n onclick=\"const container = this.closest('.bg-gray-50').querySelector('[data-app]'); const cbs = container.querySelectorAll('input[name=tools]'); const allChecked = [...cbs].every(cb => cb.checked); cbs.forEach(cb => cb.checked = !allChecked); updateCount();\">\n Toggle All\n </button>\n </div>\n <div class=\"p-4 space-y-2\" data-app=\"${escapeHtml(appId)}\">\n ${toolItems}\n </div>\n </div>`;\n })\n .join('\\n');\n\n const updateCountScript = `\n <script>\n function updateCount() {\n const all = document.querySelectorAll('input[name=\"tools\"]');\n const checked = document.querySelectorAll('input[name=\"tools\"]:checked');\n document.getElementById('selection-count').textContent = checked.length + ' of ' + all.length + ' selected';\n document.getElementById('select-all').checked = all.length > 0 && all.length === checked.length;\n }\n document.querySelectorAll('input[name=\"tools\"]').forEach(cb => cb.addEventListener('change', updateCount));\n </script>`;\n\n const content = `\n <h1 class=\"text-3xl font-bold text-gray-900 mb-4\">Select Tools to Enable</h1>\n <p class=\"text-gray-600 mb-6\">\n Choose which tools ${escapeHtml(clientName)} can access. You can change this later.\n </p>\n\n ${userInfo}\n\n <form method=\"POST\" action=\"${escapeHtml(callbackPath)}\" id=\"consent-form\">\n <input type=\"hidden\" name=\"csrf\" value=\"${escapeHtml(csrfToken)}\">\n <input type=\"hidden\" name=\"pending_auth_id\" value=\"${escapeHtml(pendingAuthId)}\">\n\n <!-- Select all toggle -->\n <div class=\"flex items-center justify-between mb-6\">\n <label class=\"flex items-center gap-3 cursor-pointer\">\n <input type=\"checkbox\" id=\"select-all\" class=\"w-5 h-5 rounded border-gray-300\" checked\n onchange=\"document.querySelectorAll('input[name=tools]').forEach(cb => cb.checked = this.checked); updateCount();\">\n <span class=\"text-gray-700\">Select all tools</span>\n </label>\n <span id=\"selection-count\" class=\"text-sm text-gray-500\">${tools.length} of ${tools.length} selected</span>\n </div>\n\n <!-- Tool groups by app -->\n <div class=\"space-y-6 mb-8\">\n ${appGroups}\n </div>\n\n <!-- Buttons -->\n <div class=\"flex gap-4\">\n <button type=\"button\" onclick=\"history.back()\"\n class=\"flex-1 px-6 py-3 text-gray-700 bg-gray-100 hover:bg-gray-200 font-medium rounded-lg transition-colors\">\n Cancel\n </button>\n <button type=\"submit\"\n class=\"flex-1 px-6 py-3 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-lg transition-colors\">\n Confirm Selection\n </button>\n </div>\n </form>\n ${updateCountScript}`;\n\n return extraWideLayout(content, { title: 'Select Tools' });\n}\n\n/**\n * Build simple login page\n */\nexport function buildLoginPage(params: {\n clientName: string;\n scope: string;\n pendingAuthId: string;\n callbackPath: string;\n}): string {\n const { clientName, scope, pendingAuthId, callbackPath } = params;\n\n const scopesHtml = scope\n ? `<div class=\"p-4 bg-gray-50 rounded-lg mb-6\">\n <p class=\"text-xs font-medium text-gray-500 uppercase tracking-wide mb-2\">Requested permissions</p>\n <p class=\"text-gray-700\">${\n scope\n .split(' ')\n .map((s) => escapeHtml(s))\n .join(', ') || 'Default access'\n }</p>\n </div>`\n : '';\n\n const content = `\n <div class=\"bg-white rounded-2xl shadow-xl p-8\">\n <h1 class=\"text-3xl font-bold text-gray-900 mb-2 text-center\">Sign In</h1>\n <p class=\"text-gray-600 mb-8 text-center\">Authorize access to ${escapeHtml(clientName)}</p>\n\n ${scopesHtml}\n\n <form method=\"GET\" action=\"${escapeHtml(callbackPath)}\">\n <input type=\"hidden\" name=\"pending_auth_id\" value=\"${escapeHtml(pendingAuthId)}\">\n\n <!-- Email -->\n <div class=\"mb-4\">\n <label for=\"email\" class=\"block text-sm font-medium text-gray-700 mb-2\">Email</label>\n <input type=\"email\" id=\"email\" name=\"email\" required placeholder=\"you@example.com\"\n class=\"w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500\">\n </div>\n\n <!-- Name (optional) -->\n <div class=\"mb-6\">\n <label for=\"name\" class=\"block text-sm font-medium text-gray-700 mb-2\">Name (optional)</label>\n <input type=\"text\" id=\"name\" name=\"name\" placeholder=\"Your name\"\n class=\"w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500\">\n </div>\n\n <!-- Submit -->\n <button type=\"submit\"\n class=\"w-full px-6 py-3 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-lg transition-colors\">\n Authorize\n </button>\n </form>\n\n <p class=\"text-center text-sm text-gray-500 mt-6\">Client: ${escapeHtml(clientName)}</p>\n </div>`;\n\n return centeredCardLayout(content, { title: 'Sign In' });\n}\n\n/**\n * Build error page\n */\nexport function buildErrorPage(params: { error: string; description: string }): string {\n const { error, description } = params;\n\n const content = `\n <div class=\"bg-white rounded-2xl shadow-xl p-8 text-center\">\n <!-- Error icon -->\n <div class=\"flex justify-center mb-6\">\n <div class=\"w-16 h-16 rounded-full bg-red-100 flex items-center justify-center\">\n <svg class=\"w-8 h-8 text-red-600\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 18L18 6M6 6l12 12\"/>\n </svg>\n </div>\n </div>\n\n <h1 class=\"text-2xl font-bold text-gray-900 mb-4\">Authorization Error</h1>\n <p class=\"mb-4\">\n <code class=\"px-2 py-1 bg-gray-100 rounded text-red-600 font-mono text-sm\">${escapeHtml(error)}</code>\n </p>\n <p class=\"text-gray-600\">${escapeHtml(description)}</p>\n </div>`;\n\n return centeredCardLayout(content, { title: 'Error' });\n}\n\n// ============================================\n// Legacy Compatibility - renderToHtml wrapper\n// ============================================\n\n/**\n * Simple wrapper for compatibility - just returns the HTML string\n * (Templates are already complete HTML documents)\n */\nexport function renderToHtml(html: string, _options?: { title?: string }): string {\n return html;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"decorator-utils.js","sourceRoot":"","sources":["../../../../src/common/decorators/decorator-utils.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Decorator Utilities for Dual-Mode Support\n *\n * This module provides utilities for creating decorators that work with both:\n * - Legacy TypeScript decorators (experimentalDecorators: true)\n * - TC39 Stage 3 decorators (native JS, used by esbuild/tsx)\n *\n * The key difference between the two modes:\n *\n * LEGACY TypeScript Method Decorator:\n * (target: prototype, propertyKey: string, descriptor: PropertyDescriptor) => void\n * - target is the class prototype (for instance methods) or class (for static)\n * - propertyKey is the method name\n * - descriptor is the property descriptor\n *\n * TC39 Stage 3 Method Decorator:\n * (target: method, context: ClassMethodDecoratorContext) => method\n * - target is the actual method function being decorated\n * - context is an object with { kind, name, static, private, addInitializer }\n * - The class isn't available during decoration (only via addInitializer at instance creation)\n *\n * @example\n * ```typescript\n * // Using the factory to create a dual-mode decorator\n * const MyDecorator = createMethodDecorator<{ stage: string }>({\n * createMetadata: (args, options) => ({\n * methodName: args.methodName,\n * stage: options.stage,\n * }),\n * onLegacyDecoration: (ctor, metadata) => {\n * // Immediately register on class (legacy mode)\n * registerOnClass(ctor, metadata);\n * },\n * });\n *\n * // Usage (works in both modes):\n * class MyFlow {\n * @MyDecorator({ stage: 'execute' })\n * async execute() {}\n * }\n * ```\n */\n\n/**\n * TC39 Stage 3 Method Decorator Context\n * @see https://github.com/tc39/proposal-decorators\n */\nexport interface TC39MethodContext {\n readonly kind: 'method';\n readonly name: string | symbol;\n readonly static: boolean;\n readonly private: boolean;\n addInitializer(initializer: () => void): void;\n}\n\n/**\n * TC39 Stage 3 Class Decorator Context\n */\nexport interface TC39ClassContext {\n readonly kind: 'class';\n readonly name: string | undefined;\n addInitializer(initializer: () => void): void;\n}\n\n/**\n * Normalized arguments passed to method decorator handlers\n */\nexport interface MethodDecoratorArgs {\n /** The method function being decorated */\n method: Function;\n /** Method name as string */\n methodName: string;\n /** Whether this is a static method */\n isStatic: boolean;\n /** Decorator mode */\n mode: 'legacy' | 'tc39';\n}\n\n/**\n * Configuration for creating a dual-mode method decorator\n */\nexport interface MethodDecoratorConfig<TOptions, TMetadata> {\n /**\n * Create metadata from decorator arguments and options\n */\n createMetadata: (args: MethodDecoratorArgs, options: TOptions) => TMetadata;\n\n /**\n * Called immediately during legacy decoration with access to the class\n * Use this to register metadata directly on the class\n */\n onLegacyDecoration?: (ctor: Function, metadata: TMetadata) => void;\n\n /**\n * Store pending metadata for TC39 mode (required)\n * The metadata will be resolved later when the class is processed\n */\n storePendingMetadata: (method: Function, metadata: TMetadata) => void;\n}\n\n/**\n * Check if decorator context is TC39 Stage 3 style\n */\nexport function isTC39MethodContext(arg: unknown): arg is TC39MethodContext {\n return typeof arg === 'object' && arg !== null && 'kind' in arg && (arg as TC39MethodContext).kind === 'method';\n}\n\n/**\n * Check if decorator context is TC39 Stage 3 class context\n */\nexport function isTC39ClassContext(arg: unknown): arg is TC39ClassContext {\n return typeof arg === 'object' && arg !== null && 'kind' in arg && (arg as TC39ClassContext).kind === 'class';\n}\n\n/**\n * Creates a method decorator that works with both legacy TypeScript and TC39 Stage 3 decorators.\n *\n * For legacy decorators: onLegacyDecoration is called immediately with class constructor\n * For TC39 decorators: storePendingMetadata is called, metadata resolved later via resolvePendingMetadataForClass\n */\nexport function createDualModeMethodDecorator<TOptions, TMetadata>(\n config: MethodDecoratorConfig<TOptions, TMetadata>,\n): (options: TOptions) => MethodDecorator {\n return (options: TOptions): MethodDecorator => {\n return (target: any, keyOrContext: any, descriptor?: PropertyDescriptor): any => {\n if (isTC39MethodContext(keyOrContext)) {\n // TC39 Stage 3 decorator style\n const context = keyOrContext;\n const methodName = String(context.name);\n const isStatic = context.static;\n const method = target; // In TC39, target is the method function itself\n\n const args: MethodDecoratorArgs = {\n method,\n methodName,\n isStatic,\n mode: 'tc39',\n };\n\n const metadata = config.createMetadata(args, options);\n config.storePendingMetadata(method, metadata);\n\n // Return the original method unchanged\n return target;\n } else {\n // Legacy TypeScript decorator style\n const key = keyOrContext;\n const methodName = String(key);\n const isStatic = typeof target === 'function';\n const method = descriptor?.value ?? target[key];\n const ctor = isStatic ? target : target.constructor;\n\n const args: MethodDecoratorArgs = {\n method,\n methodName,\n isStatic,\n mode: 'legacy',\n };\n\n const metadata = config.createMetadata(args, options);\n\n // In legacy mode, we have immediate access to the class\n if (config.onLegacyDecoration) {\n config.onLegacyDecoration(ctor, metadata);\n }\n\n // Return nothing to keep the original descriptor\n return undefined;\n }\n };\n };\n}\n\n/**\n * Storage for pending TC39 decorator metadata\n * Generic class that can be instantiated for different metadata types\n */\nexport class PendingMetadataRegistry<T> {\n private pending = new WeakMap<Function, T[]>();\n\n /**\n * Store pending metadata for a method (TC39 mode)\n */\n store(method: Function, metadata: T): void {\n const existing = this.pending.get(method) ?? [];\n existing.push(metadata);\n this.pending.set(method, existing);\n }\n\n /**\n * Get and optionally clear pending metadata for a method\n */\n consume(method: Function): T[] {\n const pending = this.pending.get(method) ?? [];\n this.pending.delete(method);\n return pending;\n }\n\n /**\n * Resolve all pending metadata for a class by scanning its prototype and static members\n */\n resolveForClass(ctor: Function, consume: boolean = true): T[] {\n const resolved: T[] = [];\n\n // Scan instance methods on prototype\n const proto = ctor.prototype;\n if (proto) {\n for (const name of Object.getOwnPropertyNames(proto)) {\n if (name === 'constructor') continue;\n try {\n const desc = Object.getOwnPropertyDescriptor(proto, name);\n const method = desc?.value;\n if (typeof method === 'function') {\n const pending = consume ? this.consume(method) : this.pending.get(method) ?? [];\n resolved.push(...pending);\n }\n } catch {\n // Ignore getter/setter errors\n }\n }\n }\n\n // Scan static methods on constructor\n for (const name of Object.getOwnPropertyNames(ctor)) {\n if (['prototype', 'length', 'name'].includes(name)) continue;\n try {\n const desc = Object.getOwnPropertyDescriptor(ctor, name);\n const method = desc?.value;\n if (typeof method === 'function') {\n const pending = consume ? this.consume(method) : this.pending.get(method) ?? [];\n resolved.push(...pending);\n }\n } catch {\n // Ignore getter/setter errors\n }\n }\n\n return resolved;\n }\n}\n\n/**\n * Creates a class decorator that works with both legacy TypeScript and TC39 Stage 3 decorators.\n */\nexport function createDualModeClassDecorator<TOptions>(\n handler: (ctor: Function, options: TOptions, context?: TC39ClassContext) => Function | void,\n): (options: TOptions) => ClassDecorator {\n return (options: TOptions): ClassDecorator => {\n return (target: any, context?: any): any => {\n if (isTC39ClassContext(context)) {\n // TC39 Stage 3 class decorator\n return handler(target, options, context) ?? target;\n } else {\n // Legacy TypeScript class decorator\n return handler(target, options) ?? target;\n }\n };\n };\n}\n"]}
1
+ {"version":3,"file":"decorator-utils.js","sourceRoot":"","sources":["../../../../src/common/decorators/decorator-utils.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Decorator Utilities for Dual-Mode Support\n *\n * This module provides utilities for creating decorators that work with both:\n * - Legacy TypeScript decorators (experimentalDecorators: true)\n * - TC39 Stage 3 decorators (native JS, used by esbuild/tsx)\n *\n * The key difference between the two modes:\n *\n * LEGACY TypeScript Method Decorator:\n * (target: prototype, propertyKey: string, descriptor: PropertyDescriptor) => void\n * - target is the class prototype (for instance methods) or class (for static)\n * - propertyKey is the method name\n * - descriptor is the property descriptor\n *\n * TC39 Stage 3 Method Decorator:\n * (target: method, context: ClassMethodDecoratorContext) => method\n * - target is the actual method function being decorated\n * - context is an object with { kind, name, static, private, addInitializer }\n * - The class isn't available during decoration (only via addInitializer at instance creation)\n *\n * @example\n * ```typescript\n * // Using the factory to create a dual-mode decorator\n * const MyDecorator = createMethodDecorator<{ stage: string }>({\n * createMetadata: (args, options) => ({\n * methodName: args.methodName,\n * stage: options.stage,\n * }),\n * onLegacyDecoration: (ctor, metadata) => {\n * // Immediately register on class (legacy mode)\n * registerOnClass(ctor, metadata);\n * },\n * });\n *\n * // Usage (works in both modes):\n * class MyFlow {\n * @MyDecorator({ stage: 'execute' })\n * async execute() {}\n * }\n * ```\n */\n\n/**\n * TC39 Stage 3 Method Decorator Context\n * @see https://github.com/tc39/proposal-decorators\n */\nexport interface TC39MethodContext {\n readonly kind: 'method';\n readonly name: string | symbol;\n readonly static: boolean;\n readonly private: boolean;\n addInitializer(initializer: () => void): void;\n}\n\n/**\n * TC39 Stage 3 Class Decorator Context\n */\nexport interface TC39ClassContext {\n readonly kind: 'class';\n readonly name: string | undefined;\n addInitializer(initializer: () => void): void;\n}\n\n/**\n * Normalized arguments passed to method decorator handlers\n */\nexport interface MethodDecoratorArgs {\n /** The method function being decorated */\n method: Function;\n /** Method name as string */\n methodName: string;\n /** Whether this is a static method */\n isStatic: boolean;\n /** Decorator mode */\n mode: 'legacy' | 'tc39';\n}\n\n/**\n * Configuration for creating a dual-mode method decorator\n */\nexport interface MethodDecoratorConfig<TOptions, TMetadata> {\n /**\n * Create metadata from decorator arguments and options\n */\n createMetadata: (args: MethodDecoratorArgs, options: TOptions) => TMetadata;\n\n /**\n * Called immediately during legacy decoration with access to the class\n * Use this to register metadata directly on the class\n */\n onLegacyDecoration?: (ctor: Function, metadata: TMetadata) => void;\n\n /**\n * Store pending metadata for TC39 mode (required)\n * The metadata will be resolved later when the class is processed\n */\n storePendingMetadata: (method: Function, metadata: TMetadata) => void;\n}\n\n/**\n * Check if decorator context is TC39 Stage 3 style\n */\nexport function isTC39MethodContext(arg: unknown): arg is TC39MethodContext {\n return typeof arg === 'object' && arg !== null && 'kind' in arg && (arg as TC39MethodContext).kind === 'method';\n}\n\n/**\n * Check if decorator context is TC39 Stage 3 class context\n */\nexport function isTC39ClassContext(arg: unknown): arg is TC39ClassContext {\n return typeof arg === 'object' && arg !== null && 'kind' in arg && (arg as TC39ClassContext).kind === 'class';\n}\n\n/**\n * Creates a method decorator that works with both legacy TypeScript and TC39 Stage 3 decorators.\n *\n * For legacy decorators: onLegacyDecoration is called immediately with class constructor\n * For TC39 decorators: storePendingMetadata is called, metadata resolved later via resolvePendingMetadataForClass\n */\nexport function createDualModeMethodDecorator<TOptions, TMetadata>(\n config: MethodDecoratorConfig<TOptions, TMetadata>,\n): (options: TOptions) => MethodDecorator {\n return (options: TOptions): MethodDecorator => {\n return (target: any, keyOrContext: any, descriptor?: PropertyDescriptor): any => {\n if (isTC39MethodContext(keyOrContext)) {\n // TC39 Stage 3 decorator style\n const context = keyOrContext;\n const methodName = String(context.name);\n const isStatic = context.static;\n const method = target; // In TC39, target is the method function itself\n\n const args: MethodDecoratorArgs = {\n method,\n methodName,\n isStatic,\n mode: 'tc39',\n };\n\n const metadata = config.createMetadata(args, options);\n config.storePendingMetadata(method, metadata);\n\n // Return the original method unchanged\n return target;\n } else {\n // Legacy TypeScript decorator style\n const key = keyOrContext;\n const methodName = String(key);\n const isStatic = typeof target === 'function';\n const method = descriptor?.value ?? target[key];\n const ctor = isStatic ? target : target.constructor;\n\n const args: MethodDecoratorArgs = {\n method,\n methodName,\n isStatic,\n mode: 'legacy',\n };\n\n const metadata = config.createMetadata(args, options);\n\n // In legacy mode, we have immediate access to the class\n if (config.onLegacyDecoration) {\n config.onLegacyDecoration(ctor, metadata);\n }\n\n // Return nothing to keep the original descriptor\n return undefined;\n }\n };\n };\n}\n\n/**\n * Storage for pending TC39 decorator metadata\n * Generic class that can be instantiated for different metadata types\n */\nexport class PendingMetadataRegistry<T> {\n private pending = new WeakMap<Function, T[]>();\n\n /**\n * Store pending metadata for a method (TC39 mode)\n */\n store(method: Function, metadata: T): void {\n const existing = this.pending.get(method) ?? [];\n existing.push(metadata);\n this.pending.set(method, existing);\n }\n\n /**\n * Get and optionally clear pending metadata for a method\n */\n consume(method: Function): T[] {\n const pending = this.pending.get(method) ?? [];\n this.pending.delete(method);\n return pending;\n }\n\n /**\n * Resolve all pending metadata for a class by scanning its prototype and static members\n */\n resolveForClass(ctor: Function, consume = true): T[] {\n const resolved: T[] = [];\n\n // Scan instance methods on prototype\n const proto = ctor.prototype;\n if (proto) {\n for (const name of Object.getOwnPropertyNames(proto)) {\n if (name === 'constructor') continue;\n try {\n const desc = Object.getOwnPropertyDescriptor(proto, name);\n const method = desc?.value;\n if (typeof method === 'function') {\n const pending = consume ? this.consume(method) : this.pending.get(method) ?? [];\n resolved.push(...pending);\n }\n } catch {\n // Ignore getter/setter errors\n }\n }\n }\n\n // Scan static methods on constructor\n for (const name of Object.getOwnPropertyNames(ctor)) {\n if (['prototype', 'length', 'name'].includes(name)) continue;\n try {\n const desc = Object.getOwnPropertyDescriptor(ctor, name);\n const method = desc?.value;\n if (typeof method === 'function') {\n const pending = consume ? this.consume(method) : this.pending.get(method) ?? [];\n resolved.push(...pending);\n }\n } catch {\n // Ignore getter/setter errors\n }\n }\n\n return resolved;\n }\n}\n\n/**\n * Creates a class decorator that works with both legacy TypeScript and TC39 Stage 3 decorators.\n */\nexport function createDualModeClassDecorator<TOptions>(\n handler: (ctor: Function, options: TOptions, context?: TC39ClassContext) => Function | void,\n): (options: TOptions) => ClassDecorator {\n return (options: TOptions): ClassDecorator => {\n return (target: any, context?: any): any => {\n if (isTC39ClassContext(context)) {\n // TC39 Stage 3 class decorator\n return handler(target, options, context) ?? target;\n } else {\n // Legacy TypeScript class decorator\n return handler(target, options) ?? target;\n }\n };\n };\n}\n"]}
@@ -4,12 +4,16 @@ exports.FrontMcp = FrontMcp;
4
4
  require("reflect-metadata");
5
5
  const tokens_1 = require("../tokens");
6
6
  const metadata_1 = require("../metadata");
7
+ const migrate_1 = require("../migrate");
8
+ const mcp_error_1 = require("../../errors/mcp.error");
7
9
  /**
8
10
  * Decorator that marks a class as a FrontMcp Server and provides metadata
9
11
  */
10
12
  function FrontMcp(providedMetadata) {
11
13
  return (target) => {
12
- const { error, data: metadata } = metadata_1.frontMcpMetadataSchema.safeParse(providedMetadata);
14
+ // Apply migration for deprecated auth.transport and session configs
15
+ const migratedMetadata = (0, migrate_1.applyMigration)(providedMetadata);
16
+ const { error, data: metadata } = metadata_1.frontMcpMetadataSchema.safeParse(migratedMetadata);
13
17
  if (error) {
14
18
  if (error.format().apps) {
15
19
  throw new Error(`Invalid metadata provided to @FrontMcp { apps: [?] }: \n${JSON.stringify(error.format().apps, null, 2)}`);
@@ -27,11 +31,30 @@ function FrontMcp(providedMetadata) {
27
31
  for (const property in metadata) {
28
32
  Reflect.defineMetadata(tokens_1.FrontMcpTokens[property] ?? property, metadata[property], target);
29
33
  }
30
- if (metadata.serve) {
34
+ // Safe check for serverless mode - process.env may not exist in Cloudflare Workers
35
+ const isServerless = typeof process !== 'undefined' && process.env?.['FRONTMCP_SERVERLESS'] === '1';
36
+ if (isServerless) {
37
+ // Serverless mode: bootstrap, prepare (no listen), store handler globally
38
+ // Use synchronous require for bundler compatibility (rspack/webpack)
39
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
40
+ const { FrontMcpInstance: ServerlessInstance, setServerlessHandler, setServerlessHandlerPromise, setServerlessHandlerError, } = require('@frontmcp/sdk');
41
+ if (!ServerlessInstance) {
42
+ throw new mcp_error_1.InternalMcpError('@frontmcp/sdk version mismatch, make sure you have the same version for all @frontmcp/* packages', 'SDK_VERSION_MISMATCH');
43
+ }
44
+ const handlerPromise = ServerlessInstance.createHandler(metadata);
45
+ setServerlessHandlerPromise(handlerPromise);
46
+ handlerPromise.then(setServerlessHandler).catch((err) => {
47
+ const e = err instanceof Error ? err : new mcp_error_1.InternalMcpError(String(err), 'SERVERLESS_INIT_FAILED');
48
+ setServerlessHandlerError(e);
49
+ console.error('[FrontMCP] Serverless initialization failed:', e);
50
+ });
51
+ }
52
+ else if (metadata.serve) {
53
+ // Normal mode: bootstrap and start server
31
54
  const sdk = '@frontmcp/sdk';
32
55
  import(sdk).then(({ FrontMcpInstance }) => {
33
56
  if (!FrontMcpInstance) {
34
- throw new Error(`${sdk} version mismatch, make sure you have the same version for all @frontmcp/* packages`);
57
+ throw new mcp_error_1.InternalMcpError(`${sdk} version mismatch, make sure you have the same version for all @frontmcp/* packages`, 'SDK_VERSION_MISMATCH');
35
58
  }
36
59
  FrontMcpInstance.bootstrap(metadata);
37
60
  });
@@ -1 +1 @@
1
- {"version":3,"file":"front-mcp.decorator.js","sourceRoot":"","sources":["../../../../src/common/decorators/front-mcp.decorator.ts"],"names":[],"mappings":";;AAQA,4BA+CC;AAvDD,4BAA0B;AAC1B,sCAA2C;AAC3C,0CAAuE;AAGvE;;GAEG;AACH,SAAgB,QAAQ,CAAC,gBAAkC;IACzD,OAAO,CAAC,MAAgB,EAAE,EAAE;QAC1B,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,iCAAsB,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QACrF,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;gBACxB,MAAM,IAAI,KAAK,CACb,2DAA2D,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAC1G,CAAC;YACJ,CAAC;YACD,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC,SAAS,EAAE,CAAC;gBAC7B,MAAM,IAAI,KAAK,CACb,gEAAgE,IAAI,CAAC,SAAS,CAC5E,KAAK,CAAC,MAAM,EAAE,CAAC,SAAS,EACxB,IAAI,EACJ,CAAC,CACF,EAAE,CACJ,CAAC;YACJ,CAAC;YACD,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,SAAS,CAAwC,CAAC;YACvF,IAAI,aAAa,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC;gBAClC,MAAM,IAAI,KAAK,CACb,8EAA8E,IAAI,CAAC,SAAS,CAC1F,aAAa,CAAC,YAAY,CAAC,EAC3B,IAAI,EACJ,CAAC,CACF,EAAE,CACJ,CAAC;YACJ,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;QAED,OAAO,CAAC,cAAc,CAAC,uBAAc,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAC1D,KAAK,MAAM,QAAQ,IAAI,QAAQ,EAAE,CAAC;YAChC,OAAO,CAAC,cAAc,CAAC,uBAAc,CAAC,QAAQ,CAAC,IAAI,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC;QAC3F,CAAC;QAED,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACnB,MAAM,GAAG,GAAG,eAAe,CAAC;YAC5B,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,gBAAgB,EAAE,EAAE,EAAE;gBACxC,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBACtB,MAAM,IAAI,KAAK,CAAC,GAAG,GAAG,qFAAqF,CAAC,CAAC;gBAC/G,CAAC;gBAED,gBAAgB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YACvC,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import 'reflect-metadata';\nimport { FrontMcpTokens } from '../tokens';\nimport { FrontMcpMetadata, frontMcpMetadataSchema } from '../metadata';\nimport { FrontMcpInstance } from '../../front-mcp';\n\n/**\n * Decorator that marks a class as a FrontMcp Server and provides metadata\n */\nexport function FrontMcp(providedMetadata: FrontMcpMetadata): ClassDecorator {\n return (target: Function) => {\n const { error, data: metadata } = frontMcpMetadataSchema.safeParse(providedMetadata);\n if (error) {\n if (error.format().apps) {\n throw new Error(\n `Invalid metadata provided to @FrontMcp { apps: [?] }: \\n${JSON.stringify(error.format().apps, null, 2)}`,\n );\n }\n if (error.format().providers) {\n throw new Error(\n `Invalid metadata provided to @FrontMcp { providers: [?] }: \\n${JSON.stringify(\n error.format().providers,\n null,\n 2,\n )}`,\n );\n }\n const loggingFormat = error.format()['logging'] as Record<string, unknown> | undefined;\n if (loggingFormat?.['transports']) {\n throw new Error(\n `Invalid metadata provided to @FrontMcp { logging: { transports: [?] } }: \\n${JSON.stringify(\n loggingFormat['transports'],\n null,\n 2,\n )}`,\n );\n }\n throw error;\n }\n\n Reflect.defineMetadata(FrontMcpTokens.type, true, target);\n for (const property in metadata) {\n Reflect.defineMetadata(FrontMcpTokens[property] ?? property, metadata[property], target);\n }\n\n if (metadata.serve) {\n const sdk = '@frontmcp/sdk';\n import(sdk).then(({ FrontMcpInstance }) => {\n if (!FrontMcpInstance) {\n throw new Error(`${sdk} version mismatch, make sure you have the same version for all @frontmcp/* packages`);\n }\n\n FrontMcpInstance.bootstrap(metadata);\n });\n }\n };\n}\n"]}
1
+ {"version":3,"file":"front-mcp.decorator.js","sourceRoot":"","sources":["../../../../src/common/decorators/front-mcp.decorator.ts"],"names":[],"mappings":"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","sourcesContent":["import 'reflect-metadata';\nimport { FrontMcpTokens } from '../tokens';\nimport { FrontMcpMetadata, frontMcpMetadataSchema } from '../metadata';\nimport { FrontMcpInstance } from '../../front-mcp';\nimport { applyMigration } from '../migrate';\nimport { InternalMcpError } from '../../errors/mcp.error';\n\n/**\n * Decorator that marks a class as a FrontMcp Server and provides metadata\n */\nexport function FrontMcp(providedMetadata: FrontMcpMetadata): ClassDecorator {\n return (target: Function) => {\n // Apply migration for deprecated auth.transport and session configs\n const migratedMetadata = applyMigration(providedMetadata);\n const { error, data: metadata } = frontMcpMetadataSchema.safeParse(migratedMetadata);\n if (error) {\n if (error.format().apps) {\n throw new Error(\n `Invalid metadata provided to @FrontMcp { apps: [?] }: \\n${JSON.stringify(error.format().apps, null, 2)}`,\n );\n }\n if (error.format().providers) {\n throw new Error(\n `Invalid metadata provided to @FrontMcp { providers: [?] }: \\n${JSON.stringify(\n error.format().providers,\n null,\n 2,\n )}`,\n );\n }\n const loggingFormat = error.format()['logging'] as Record<string, unknown> | undefined;\n if (loggingFormat?.['transports']) {\n throw new Error(\n `Invalid metadata provided to @FrontMcp { logging: { transports: [?] } }: \\n${JSON.stringify(\n loggingFormat['transports'],\n null,\n 2,\n )}`,\n );\n }\n throw error;\n }\n\n Reflect.defineMetadata(FrontMcpTokens.type, true, target);\n for (const property in metadata) {\n Reflect.defineMetadata(FrontMcpTokens[property] ?? property, metadata[property], target);\n }\n\n // Safe check for serverless mode - process.env may not exist in Cloudflare Workers\n const isServerless = typeof process !== 'undefined' && process.env?.['FRONTMCP_SERVERLESS'] === '1';\n\n if (isServerless) {\n // Serverless mode: bootstrap, prepare (no listen), store handler globally\n // Use synchronous require for bundler compatibility (rspack/webpack)\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const {\n FrontMcpInstance: ServerlessInstance,\n setServerlessHandler,\n setServerlessHandlerPromise,\n setServerlessHandlerError,\n }: {\n FrontMcpInstance: typeof FrontMcpInstance;\n setServerlessHandler: (handler: unknown) => void;\n setServerlessHandlerPromise: (promise: Promise<unknown>) => void;\n setServerlessHandlerError: (error: Error) => void;\n } = require('@frontmcp/sdk');\n\n if (!ServerlessInstance) {\n throw new InternalMcpError(\n '@frontmcp/sdk version mismatch, make sure you have the same version for all @frontmcp/* packages',\n 'SDK_VERSION_MISMATCH',\n );\n }\n\n const handlerPromise = ServerlessInstance.createHandler(metadata);\n setServerlessHandlerPromise(handlerPromise);\n handlerPromise.then(setServerlessHandler).catch((err: unknown) => {\n const e = err instanceof Error ? err : new InternalMcpError(String(err), 'SERVERLESS_INIT_FAILED');\n setServerlessHandlerError(e);\n console.error('[FrontMCP] Serverless initialization failed:', e);\n });\n } else if (metadata.serve) {\n // Normal mode: bootstrap and start server\n const sdk = '@frontmcp/sdk';\n import(sdk).then(({ FrontMcpInstance }) => {\n if (!FrontMcpInstance) {\n throw new InternalMcpError(\n `${sdk} version mismatch, make sure you have the same version for all @frontmcp/* packages`,\n 'SDK_VERSION_MISMATCH',\n );\n }\n\n FrontMcpInstance.bootstrap(metadata);\n });\n }\n };\n}\n"]}
@@ -13,5 +13,4 @@ export * from './flow/flow.utils';
13
13
  export * from './interfaces/tool-hook.interface';
14
14
  export * from './interfaces/session-hook.interface';
15
15
  export * from './interfaces/auth-hook.interface';
16
- export * from './providers/session.provider';
17
16
  export * from './providers/base-config.provider';
@@ -16,6 +16,5 @@ tslib_1.__exportStar(require("./flow/flow.utils"), exports);
16
16
  tslib_1.__exportStar(require("./interfaces/tool-hook.interface"), exports);
17
17
  tslib_1.__exportStar(require("./interfaces/session-hook.interface"), exports);
18
18
  tslib_1.__exportStar(require("./interfaces/auth-hook.interface"), exports);
19
- tslib_1.__exportStar(require("./providers/session.provider"), exports);
20
19
  tslib_1.__exportStar(require("./providers/base-config.provider"), exports);
21
20
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/common/index.ts"],"names":[],"mappings":";;;AAAA,sDAA4B;AAC5B,uDAA6B;AAC7B,kDAAwB;AACxB,qDAA2B;AAC3B,uDAA6B;AAC7B,mDAAyB;AACzB,oDAA0B;AAC1B,oDAA0B;AAC1B,oDAA0B;AAC1B,kDAAwB;AACxB,oDAA0B;AAC1B,4DAAkC;AAElC,2EAAiD;AACjD,8EAAoD;AACpD,2EAAiD;AAEjD,uEAA6C;AAC7C,2EAAiD","sourcesContent":["export * from './constants';\nexport * from './decorators';\nexport * from './types';\nexport * from './metadata';\nexport * from './interfaces';\nexport * from './tokens';\nexport * from './dynamic';\nexport * from './records';\nexport * from './entries';\nexport * from './utils';\nexport * from './schemas';\nexport * from './flow/flow.utils';\n\nexport * from './interfaces/tool-hook.interface';\nexport * from './interfaces/session-hook.interface';\nexport * from './interfaces/auth-hook.interface';\n\nexport * from './providers/session.provider';\nexport * from './providers/base-config.provider';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/common/index.ts"],"names":[],"mappings":";;;AAAA,sDAA4B;AAC5B,uDAA6B;AAC7B,kDAAwB;AACxB,qDAA2B;AAC3B,uDAA6B;AAC7B,mDAAyB;AACzB,oDAA0B;AAC1B,oDAA0B;AAC1B,oDAA0B;AAC1B,kDAAwB;AACxB,oDAA0B;AAC1B,4DAAkC;AAElC,2EAAiD;AACjD,8EAAoD;AACpD,2EAAiD;AAEjD,2EAAiD","sourcesContent":["export * from './constants';\nexport * from './decorators';\nexport * from './types';\nexport * from './metadata';\nexport * from './interfaces';\nexport * from './tokens';\nexport * from './dynamic';\nexport * from './records';\nexport * from './entries';\nexport * from './utils';\nexport * from './schemas';\nexport * from './flow/flow.utils';\n\nexport * from './interfaces/tool-hook.interface';\nexport * from './interfaces/session-hook.interface';\nexport * from './interfaces/auth-hook.interface';\n\nexport * from './providers/base-config.provider';\n"]}
@@ -3,10 +3,16 @@ import { ToolType } from './tool.interface';
3
3
  import { ResourceType } from './resource.interface';
4
4
  import { PromptType } from './prompt.interface';
5
5
  import { AdapterMetadata } from '../metadata';
6
+ import { FrontMcpLogger } from './logger.interface';
6
7
  export interface AdapterInterface {
7
8
  options: {
8
9
  name: string;
9
10
  } & Record<string, unknown>;
11
+ /**
12
+ * Optional method to receive the SDK logger.
13
+ * Called by the SDK before fetch() if implemented.
14
+ */
15
+ setLogger?: (logger: FrontMcpLogger) => void;
10
16
  fetch: () => Promise<FrontMcpAdapterResponse> | FrontMcpAdapterResponse;
11
17
  }
12
18
  export interface FrontMcpAdapterResponse {
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.interface.js","sourceRoot":"","sources":["../../../../src/common/interfaces/adapter.interface.ts"],"names":[],"mappings":"","sourcesContent":["import {ClassType, FactoryType, Token, Type, ValueType} from './base.interface';\nimport {ToolType} from './tool.interface';\nimport {ResourceType} from './resource.interface';\nimport {PromptType} from './prompt.interface';\nimport {AdapterMetadata} from '../metadata';\n\nexport interface AdapterInterface {\n options: { name: string } & Record<string, unknown>;\n fetch: () => Promise<FrontMcpAdapterResponse> | FrontMcpAdapterResponse;\n}\n\nexport interface FrontMcpAdapterResponse {\n tools?: ToolType[];\n resources?: ResourceType[];\n prompts?: PromptType[];\n}\n\n\nexport type AdapterClassType<Provide> = ClassType<Provide> & AdapterMetadata;\nexport type AdapterValueType<Provide> = ValueType<Provide> & AdapterMetadata;\nexport type AdapterFactoryType<Provide, Tokens extends readonly Token[]> =\n FactoryType<Provide, Tokens>\n & AdapterMetadata;\n\n\nexport type AdapterType<Provide extends AdapterInterface = any> =\n | Type<Provide>\n | AdapterClassType<Provide>\n | AdapterValueType<Provide>\n | AdapterFactoryType<Provide, any[]>\n\n"]}
1
+ {"version":3,"file":"adapter.interface.js","sourceRoot":"","sources":["../../../../src/common/interfaces/adapter.interface.ts"],"names":[],"mappings":"","sourcesContent":["import { ClassType, FactoryType, Token, Type, ValueType } from './base.interface';\nimport { ToolType } from './tool.interface';\nimport { ResourceType } from './resource.interface';\nimport { PromptType } from './prompt.interface';\nimport { AdapterMetadata } from '../metadata';\nimport { FrontMcpLogger } from './logger.interface';\n\nexport interface AdapterInterface {\n options: { name: string } & Record<string, unknown>;\n /**\n * Optional method to receive the SDK logger.\n * Called by the SDK before fetch() if implemented.\n */\n setLogger?: (logger: FrontMcpLogger) => void;\n fetch: () => Promise<FrontMcpAdapterResponse> | FrontMcpAdapterResponse;\n}\n\nexport interface FrontMcpAdapterResponse {\n tools?: ToolType[];\n resources?: ResourceType[];\n prompts?: PromptType[];\n}\n\nexport type AdapterClassType<Provide> = ClassType<Provide> & AdapterMetadata;\nexport type AdapterValueType<Provide> = ValueType<Provide> & AdapterMetadata;\nexport type AdapterFactoryType<Provide, Tokens extends readonly Token[]> = FactoryType<Provide, Tokens> &\n AdapterMetadata;\n\nexport type AdapterType<Provide extends AdapterInterface = any> =\n | Type<Provide>\n | AdapterClassType<Provide>\n | AdapterValueType<Provide>\n | AdapterFactoryType<Provide, any[]>;\n"]}
@@ -4,13 +4,14 @@ import { FrontMcpLogger } from './logger.interface';
4
4
  import { URL } from 'url';
5
5
  import { AuthInfo } from '@modelcontextprotocol/sdk/server/auth/types.js';
6
6
  import { ScopeEntry } from '../entries';
7
+ import { FrontMcpContext } from '../../context';
7
8
  /**
8
9
  * Base constructor arguments for all execution contexts.
9
10
  */
10
11
  export type ExecutionContextBaseArgs = {
11
12
  providers: ProviderRegistryInterface;
12
13
  logger: FrontMcpLogger;
13
- authInfo: AuthInfo;
14
+ authInfo: Partial<AuthInfo>;
14
15
  };
15
16
  /**
16
17
  * Abstract base class for execution contexts (tools, resources, prompts, etc.).
@@ -18,7 +19,10 @@ export type ExecutionContextBaseArgs = {
18
19
  */
19
20
  export declare abstract class ExecutionContextBase<Out = unknown> {
20
21
  private providers;
21
- readonly authInfo: AuthInfo;
22
+ /**
23
+ * @deprecated Use `context.authInfo` instead. Will be removed in v2.0.
24
+ */
25
+ private readonly _authInfo;
22
26
  /** Unique identifier for this execution run */
23
27
  protected readonly runId: string;
24
28
  protected readonly logger: FrontMcpLogger;
@@ -27,6 +31,43 @@ export declare abstract class ExecutionContextBase<Out = unknown> {
27
31
  /** Error if execution failed */
28
32
  private _error?;
29
33
  constructor(args: ExecutionContextBaseArgs);
34
+ /**
35
+ * Get the current FrontMcpContext.
36
+ *
37
+ * Provides access to requestId, traceId, sessionId, authInfo,
38
+ * timing marks, request metadata, transport, and context-aware fetch.
39
+ *
40
+ * @throws RequestContextNotAvailableError if called outside of a context scope
41
+ */
42
+ get context(): FrontMcpContext;
43
+ /**
44
+ * Try to get the context, returning undefined if not available.
45
+ *
46
+ * Use this when context may not be available (e.g., during initialization).
47
+ */
48
+ tryGetContext(): FrontMcpContext | undefined;
49
+ /**
50
+ * @deprecated Use `context.authInfo` instead. Will be removed in v2.0.
51
+ *
52
+ * Get authentication information for the current request.
53
+ */
54
+ get authInfo(): Partial<AuthInfo>;
55
+ /**
56
+ * Get authentication information for the current request.
57
+ *
58
+ * Prefers context.authInfo when available (the recommended source),
59
+ * falls back to the legacy authInfo property for backward compatibility.
60
+ *
61
+ * Returns Partial<AuthInfo> because auth info is progressively populated
62
+ * during the request lifecycle. Callers should check for required fields.
63
+ */
64
+ getAuthInfo(): Partial<AuthInfo>;
65
+ /**
66
+ * Get a child logger with request context attached.
67
+ *
68
+ * The logger includes requestId, traceId, and sessionId in its context.
69
+ */
70
+ protected get contextLogger(): FrontMcpLogger;
30
71
  /**
31
72
  * Get a dependency from the provider registry.
32
73
  * @throws Error if the dependency is not found
@@ -49,7 +90,15 @@ export declare abstract class ExecutionContextBase<Out = unknown> {
49
90
  */
50
91
  mark(stage: string): void;
51
92
  /**
52
- * Fetch a URL using the standard fetch API.
93
+ * Fetch a URL with context-aware header injection.
94
+ *
95
+ * When FrontMcpContext is available, delegates to ctx.fetch() which:
96
+ * - Auto-injects Authorization header (if authInfo.token is available)
97
+ * - Auto-injects W3C traceparent header for distributed tracing
98
+ * - Auto-injects x-request-id header
99
+ * - Auto-injects custom headers from request metadata
100
+ *
101
+ * Falls back to standard fetch if context is not available.
53
102
  */
54
103
  fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
55
104
  /**
@@ -4,13 +4,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.ExecutionContextBase = void 0;
5
5
  const crypto_1 = require("crypto");
6
6
  const flow_interface_1 = require("./flow.interface");
7
+ const context_1 = require("../../context");
8
+ const mcp_error_1 = require("../../errors/mcp.error");
7
9
  /**
8
10
  * Abstract base class for execution contexts (tools, resources, prompts, etc.).
9
11
  * Provides common functionality for dependency injection, logging, and flow control.
10
12
  */
11
13
  class ExecutionContextBase {
12
14
  providers;
13
- authInfo;
15
+ /**
16
+ * @deprecated Use `context.authInfo` instead. Will be removed in v2.0.
17
+ */
18
+ _authInfo;
14
19
  /** Unique identifier for this execution run */
15
20
  runId;
16
21
  logger;
@@ -23,7 +28,75 @@ class ExecutionContextBase {
23
28
  this.runId = (0, crypto_1.randomUUID)();
24
29
  this.providers = providers;
25
30
  this.logger = logger;
26
- this.authInfo = authInfo;
31
+ this._authInfo = authInfo;
32
+ }
33
+ /**
34
+ * Get the current FrontMcpContext.
35
+ *
36
+ * Provides access to requestId, traceId, sessionId, authInfo,
37
+ * timing marks, request metadata, transport, and context-aware fetch.
38
+ *
39
+ * @throws RequestContextNotAvailableError if called outside of a context scope
40
+ */
41
+ get context() {
42
+ try {
43
+ return this.providers.get(context_1.FRONTMCP_CONTEXT);
44
+ }
45
+ catch {
46
+ // Context not available (likely called during initialization or outside request scope)
47
+ throw new mcp_error_1.RequestContextNotAvailableError();
48
+ }
49
+ }
50
+ /**
51
+ * Try to get the context, returning undefined if not available.
52
+ *
53
+ * Use this when context may not be available (e.g., during initialization).
54
+ */
55
+ tryGetContext() {
56
+ try {
57
+ return this.providers.get(context_1.FRONTMCP_CONTEXT);
58
+ }
59
+ catch {
60
+ return undefined;
61
+ }
62
+ }
63
+ /**
64
+ * @deprecated Use `context.authInfo` instead. Will be removed in v2.0.
65
+ *
66
+ * Get authentication information for the current request.
67
+ */
68
+ get authInfo() {
69
+ return this._authInfo;
70
+ }
71
+ /**
72
+ * Get authentication information for the current request.
73
+ *
74
+ * Prefers context.authInfo when available (the recommended source),
75
+ * falls back to the legacy authInfo property for backward compatibility.
76
+ *
77
+ * Returns Partial<AuthInfo> because auth info is progressively populated
78
+ * during the request lifecycle. Callers should check for required fields.
79
+ */
80
+ getAuthInfo() {
81
+ const ctx = this.tryGetContext();
82
+ if (ctx) {
83
+ return ctx.authInfo;
84
+ }
85
+ return this._authInfo;
86
+ }
87
+ /**
88
+ * Get a child logger with request context attached.
89
+ *
90
+ * The logger includes requestId, traceId, and sessionId in its context.
91
+ */
92
+ get contextLogger() {
93
+ try {
94
+ return this.context.getLogger(this.logger);
95
+ }
96
+ catch {
97
+ // Fallback if context not available
98
+ return this.logger;
99
+ }
27
100
  }
28
101
  /**
29
102
  * Get a dependency from the provider registry.
@@ -65,9 +138,21 @@ class ExecutionContextBase {
65
138
  this.activeStage = stage;
66
139
  }
67
140
  /**
68
- * Fetch a URL using the standard fetch API.
141
+ * Fetch a URL with context-aware header injection.
142
+ *
143
+ * When FrontMcpContext is available, delegates to ctx.fetch() which:
144
+ * - Auto-injects Authorization header (if authInfo.token is available)
145
+ * - Auto-injects W3C traceparent header for distributed tracing
146
+ * - Auto-injects x-request-id header
147
+ * - Auto-injects custom headers from request metadata
148
+ *
149
+ * Falls back to standard fetch if context is not available.
69
150
  */
70
151
  fetch(input, init) {
152
+ const ctx = this.tryGetContext();
153
+ if (ctx) {
154
+ return ctx.fetch(input, init);
155
+ }
71
156
  return fetch(input, init);
72
157
  }
73
158
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"execution-context.interface.js","sourceRoot":"","sources":["../../../../src/common/interfaces/execution-context.interface.ts"],"names":[],"mappings":";AAAA,sEAAsE;;;AAEtE,mCAAoC;AAIpC,qDAA+C;AAc/C;;;GAGG;AACH,MAAsB,oBAAoB;IAChC,SAAS,CAA4B;IACpC,QAAQ,CAAW;IAE5B,+CAA+C;IAC5B,KAAK,CAAS;IACd,MAAM,CAAiB;IAE1C,gDAAgD;IACtC,WAAW,GAAG,MAAM,CAAC;IAE/B,gCAAgC;IACxB,MAAM,CAAS;IAEvB,YAAY,IAA8B;QACxC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;QAC7C,IAAI,CAAC,KAAK,GAAG,IAAA,mBAAU,GAAE,CAAC;QAC1B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED;;;OAGG;IACH,GAAG,CAAI,KAAe;QACpB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,MAAM,CAAI,KAAe;QACvB,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,GAAG,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACvD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,0BAA0B,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;YACpE,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IAED;;OAEG;IACO,IAAI,CAAC,GAAU;QACvB,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC;QAClB,4BAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,IAAI,CAAC,KAAa;QAChB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAwB,EAAE,IAAkB;QAChD,OAAO,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED;;OAEG;IACH,IAAc,KAAK;QACjB,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;CACF;AA9ED,oDA8EC","sourcesContent":["// file: libs/sdk/src/common/interfaces/execution-context.interface.ts\n\nimport { randomUUID } from 'crypto';\nimport { Token } from './base.interface';\nimport { ProviderRegistryInterface } from './internal';\nimport { FrontMcpLogger } from './logger.interface';\nimport { FlowControl } from './flow.interface';\nimport { URL } from 'url';\nimport { AuthInfo } from '@modelcontextprotocol/sdk/server/auth/types.js';\nimport { ScopeEntry } from '../entries';\n\n/**\n * Base constructor arguments for all execution contexts.\n */\nexport type ExecutionContextBaseArgs = {\n providers: ProviderRegistryInterface;\n logger: FrontMcpLogger;\n authInfo: AuthInfo;\n};\n\n/**\n * Abstract base class for execution contexts (tools, resources, prompts, etc.).\n * Provides common functionality for dependency injection, logging, and flow control.\n */\nexport abstract class ExecutionContextBase<Out = unknown> {\n private providers: ProviderRegistryInterface;\n readonly authInfo: AuthInfo;\n\n /** Unique identifier for this execution run */\n protected readonly runId: string;\n protected readonly logger: FrontMcpLogger;\n\n /** Current stage name for tracking/debugging */\n protected activeStage = 'init';\n\n /** Error if execution failed */\n private _error?: Error;\n\n constructor(args: ExecutionContextBaseArgs) {\n const { providers, logger, authInfo } = args;\n this.runId = randomUUID();\n this.providers = providers;\n this.logger = logger;\n this.authInfo = authInfo;\n }\n\n /**\n * Get a dependency from the provider registry.\n * @throws Error if the dependency is not found\n */\n get<T>(token: Token<T>): T {\n return this.providers.get(token);\n }\n\n /**\n * Get the current scope.\n */\n get scope(): ScopeEntry {\n return this.providers.getScope();\n }\n\n /**\n * Try to get a dependency, returning undefined if not found.\n */\n tryGet<T>(token: Token<T>): T | undefined {\n try {\n return this.providers.get(token);\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n this.logger.warn(`Failed to get provider ${String(token)}: ${msg}`);\n return undefined;\n }\n }\n\n /**\n * Fail the execution and trigger error handling.\n */\n protected fail(err: Error): never {\n this._error = err;\n FlowControl.fail(err);\n }\n\n /**\n * Mark the current execution stage (for debugging/tracking).\n */\n mark(stage: string): void {\n this.activeStage = stage;\n }\n\n /**\n * Fetch a URL using the standard fetch API.\n */\n fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response> {\n return fetch(input, init);\n }\n\n /**\n * Get the current error, if any.\n */\n protected get error(): Error | undefined {\n return this._error;\n }\n}\n"]}
1
+ {"version":3,"file":"execution-context.interface.js","sourceRoot":"","sources":["../../../../src/common/interfaces/execution-context.interface.ts"],"names":[],"mappings":"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","sourcesContent":["// file: libs/sdk/src/common/interfaces/execution-context.interface.ts\n\nimport { randomUUID } from 'crypto';\nimport { Token } from './base.interface';\nimport { ProviderRegistryInterface } from './internal';\nimport { FrontMcpLogger } from './logger.interface';\nimport { FlowControl } from './flow.interface';\nimport { URL } from 'url';\nimport { AuthInfo } from '@modelcontextprotocol/sdk/server/auth/types.js';\nimport { ScopeEntry } from '../entries';\nimport { FrontMcpContext, FRONTMCP_CONTEXT } from '../../context';\nimport { RequestContextNotAvailableError } from '../../errors/mcp.error';\n\n/**\n * Base constructor arguments for all execution contexts.\n */\nexport type ExecutionContextBaseArgs = {\n providers: ProviderRegistryInterface;\n logger: FrontMcpLogger;\n authInfo: Partial<AuthInfo>;\n};\n\n/**\n * Abstract base class for execution contexts (tools, resources, prompts, etc.).\n * Provides common functionality for dependency injection, logging, and flow control.\n */\nexport abstract class ExecutionContextBase<Out = unknown> {\n private providers: ProviderRegistryInterface;\n\n /**\n * @deprecated Use `context.authInfo` instead. Will be removed in v2.0.\n */\n private readonly _authInfo: Partial<AuthInfo>;\n\n /** Unique identifier for this execution run */\n protected readonly runId: string;\n protected readonly logger: FrontMcpLogger;\n\n /** Current stage name for tracking/debugging */\n protected activeStage = 'init';\n\n /** Error if execution failed */\n private _error?: Error;\n\n constructor(args: ExecutionContextBaseArgs) {\n const { providers, logger, authInfo } = args;\n this.runId = randomUUID();\n this.providers = providers;\n this.logger = logger;\n this._authInfo = authInfo;\n }\n\n /**\n * Get the current FrontMcpContext.\n *\n * Provides access to requestId, traceId, sessionId, authInfo,\n * timing marks, request metadata, transport, and context-aware fetch.\n *\n * @throws RequestContextNotAvailableError if called outside of a context scope\n */\n get context(): FrontMcpContext {\n try {\n return this.providers.get(FRONTMCP_CONTEXT as Token<FrontMcpContext>);\n } catch {\n // Context not available (likely called during initialization or outside request scope)\n throw new RequestContextNotAvailableError();\n }\n }\n\n /**\n * Try to get the context, returning undefined if not available.\n *\n * Use this when context may not be available (e.g., during initialization).\n */\n tryGetContext(): FrontMcpContext | undefined {\n try {\n return this.providers.get(FRONTMCP_CONTEXT as Token<FrontMcpContext>);\n } catch {\n return undefined;\n }\n }\n\n /**\n * @deprecated Use `context.authInfo` instead. Will be removed in v2.0.\n *\n * Get authentication information for the current request.\n */\n get authInfo(): Partial<AuthInfo> {\n return this._authInfo;\n }\n\n /**\n * Get authentication information for the current request.\n *\n * Prefers context.authInfo when available (the recommended source),\n * falls back to the legacy authInfo property for backward compatibility.\n *\n * Returns Partial<AuthInfo> because auth info is progressively populated\n * during the request lifecycle. Callers should check for required fields.\n */\n getAuthInfo(): Partial<AuthInfo> {\n const ctx = this.tryGetContext();\n if (ctx) {\n return ctx.authInfo;\n }\n return this._authInfo;\n }\n\n /**\n * Get a child logger with request context attached.\n *\n * The logger includes requestId, traceId, and sessionId in its context.\n */\n protected get contextLogger(): FrontMcpLogger {\n try {\n return this.context.getLogger(this.logger);\n } catch {\n // Fallback if context not available\n return this.logger;\n }\n }\n\n /**\n * Get a dependency from the provider registry.\n * @throws Error if the dependency is not found\n */\n get<T>(token: Token<T>): T {\n return this.providers.get(token);\n }\n\n /**\n * Get the current scope.\n */\n get scope(): ScopeEntry {\n return this.providers.getScope();\n }\n\n /**\n * Try to get a dependency, returning undefined if not found.\n */\n tryGet<T>(token: Token<T>): T | undefined {\n try {\n return this.providers.get(token);\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n this.logger.warn(`Failed to get provider ${String(token)}: ${msg}`);\n return undefined;\n }\n }\n\n /**\n * Fail the execution and trigger error handling.\n */\n protected fail(err: Error): never {\n this._error = err;\n FlowControl.fail(err);\n }\n\n /**\n * Mark the current execution stage (for debugging/tracking).\n */\n mark(stage: string): void {\n this.activeStage = stage;\n }\n\n /**\n * Fetch a URL with context-aware header injection.\n *\n * When FrontMcpContext is available, delegates to ctx.fetch() which:\n * - Auto-injects Authorization header (if authInfo.token is available)\n * - Auto-injects W3C traceparent header for distributed tracing\n * - Auto-injects x-request-id header\n * - Auto-injects custom headers from request metadata\n *\n * Falls back to standard fetch if context is not available.\n */\n fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response> {\n const ctx = this.tryGetContext();\n if (ctx) {\n return ctx.fetch(input, init);\n }\n return fetch(input, init);\n }\n\n /**\n * Get the current error, if any.\n */\n protected get error(): Error | undefined {\n return this._error;\n }\n}\n"]}
@@ -4,6 +4,7 @@ import { z } from 'zod';
4
4
  import { HookEntry, ScopeEntry } from '../entries';
5
5
  import { FlowStateOf } from './internal/flow.utils';
6
6
  import { FrontMcpLogger } from './logger.interface';
7
+ import type { FrontMcpContext } from '../../context/frontmcp-context';
7
8
  export type FlowInputOf<N extends FlowName> = z.infer<ExtendFlows[N]['input']>;
8
9
  export type FlowOutputOf<N extends FlowName> = z.infer<ExtendFlows[N]['output']>;
9
10
  export type FlowPlanOf<N extends FlowName> = ExtendFlows[N]['plan'];
@@ -37,5 +38,17 @@ export declare abstract class FlowBase<N extends FlowName = FlowName> {
37
38
  protected abort(message: string): void;
38
39
  protected next(): void;
39
40
  protected handled(): void;
41
+ /**
42
+ * Get the current FrontMcpContext from AsyncLocalStorage.
43
+ * Available in all stages after context initialization.
44
+ *
45
+ * @throws Error if not in a context scope
46
+ */
47
+ protected get context(): FrontMcpContext;
48
+ /**
49
+ * Safely try to get FrontMcpContext (returns undefined if not available).
50
+ * Use this when context might not be available (e.g., non-HTTP flows).
51
+ */
52
+ protected tryGetContext(): FrontMcpContext | undefined;
40
53
  }
41
54
  export type FlowType<Provide = FlowBase<any>> = Type<Provide>;
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.FlowBase = exports.FlowControl = void 0;
4
4
  const flow_utils_1 = require("./internal/flow.utils");
5
+ const frontmcp_context_storage_1 = require("../../context/frontmcp-context-storage");
5
6
  class FlowControl extends Error {
6
7
  type;
7
8
  output;
@@ -66,6 +67,29 @@ class FlowBase {
66
67
  handled() {
67
68
  throw FlowControl.handled();
68
69
  }
70
+ /**
71
+ * Get the current FrontMcpContext from AsyncLocalStorage.
72
+ * Available in all stages after context initialization.
73
+ *
74
+ * @throws Error if not in a context scope
75
+ */
76
+ get context() {
77
+ const storage = this.scope.providers.get(frontmcp_context_storage_1.FrontMcpContextStorage);
78
+ return storage.getStoreOrThrow();
79
+ }
80
+ /**
81
+ * Safely try to get FrontMcpContext (returns undefined if not available).
82
+ * Use this when context might not be available (e.g., non-HTTP flows).
83
+ */
84
+ tryGetContext() {
85
+ try {
86
+ const storage = this.scope.providers.get(frontmcp_context_storage_1.FrontMcpContextStorage);
87
+ return storage.getStore();
88
+ }
89
+ catch {
90
+ return undefined;
91
+ }
92
+ }
69
93
  }
70
94
  exports.FlowBase = FlowBase;
71
95
  //# sourceMappingURL=flow.interface.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"flow.interface.js","sourceRoot":"","sources":["../../../../src/common/interfaces/flow.interface.ts"],"names":[],"mappings":";;;AAIA,sDAA+D;AAY/D,MAAa,WAAY,SAAQ,KAAK;IACR;IAAuC;IAAnE,YAA4B,IAAqB,EAAkB,MAAW;QAC5E,KAAK,EAAE,CAAC;QADkB,SAAI,GAAJ,IAAI,CAAiB;QAAkB,WAAM,GAAN,MAAM,CAAK;IAE9E,CAAC;IAED,MAAM,CAAC,OAAO,CAAI,MAAS;QACzB,MAAM,IAAI,WAAW,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,CAAC,IAAI;QACT,MAAM,IAAI,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACtC,CAAC;IAED,MAAM,CAAC,OAAO;QACZ,MAAM,IAAI,WAAW,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACzC,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,KAAY;QACtB,MAAM,IAAI,WAAW,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,MAAc;QACzB,MAAM,IAAI,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACzC,CAAC;CACF;AAxBD,kCAwBC;AAED,uCAAuC;AACvC,MAAsB,QAAQ;IAMP;IACV;IACU;IACA;IACA;IATX,KAAK,CAAiB;IAChC,KAAK,GAAmB,sBAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC7C,WAAW,CAAiB;IAE5B,YACqB,QAAyB,EACnC,QAAuC,EAC7B,KAAiB,EACjB,kBAAgD,EAChD,OAAoC,IAAI,GAAG,EAAE;QAJ7C,aAAQ,GAAR,QAAQ,CAAiB;QACnC,aAAQ,GAAR,QAAQ,CAA+B;QAC7B,UAAK,GAAL,KAAK,CAAY;QACjB,uBAAkB,GAAlB,kBAAkB,CAA8B;QAChD,SAAI,GAAJ,IAAI,CAAyC;QAEhE,IAAI,CAAC,KAAK,GAAI,QAAQ,CAAC,WAAmB,EAAE,KAAK,EAAE,CAAC,QAAQ,CAAC,CAAC;QAC9D,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC;IAClC,CAAC;IAED,GAAG,CAAI,KAAe;QACpB,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAM,CAAC;QAC3D,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IAED,OAAO,CAAC,MAAuB;QAC7B,MAAM,WAAW,CAAC,OAAO,CAAE,IAAI,CAAC,QAAQ,CAAC,YAAiC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IAC5F,CAAC;IAED,IAAI,CAAC,KAAY;QACf,MAAM,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;IAES,KAAK,CAAC,OAAe;QAC7B,MAAM,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAES,IAAI;QACZ,MAAM,WAAW,CAAC,IAAI,EAAE,CAAC;IAC3B,CAAC;IAES,OAAO;QACf,MAAM,WAAW,CAAC,OAAO,EAAE,CAAC;IAC9B,CAAC;CACF;AAxCD,4BAwCC","sourcesContent":["import { Token, Type } from './base.interface';\nimport { FlowMetadata, FlowName } from '../metadata';\nimport { z } from 'zod';\nimport { HookEntry, ScopeEntry } from '../entries';\nimport { FlowState, FlowStateOf } from './internal/flow.utils';\nimport { FrontMcpLogger } from './logger.interface';\n\nexport type FlowInputOf<N extends FlowName> = z.infer<ExtendFlows[N]['input']>;\nexport type FlowOutputOf<N extends FlowName> = z.infer<ExtendFlows[N]['output']>;\nexport type FlowPlanOf<N extends FlowName> = ExtendFlows[N]['plan'];\nexport type FlowCtxOf<N extends FlowName> = ExtendFlows[N]['ctx'];\nexport type FlowStagesOf<N extends FlowName> = ExtendFlows[N]['stage'];\nexport type FlowExecuteStagesOf<N extends FlowName> = ExtendFlows[N]['executeStage'];\n\nexport type FlowControlType = 'respond' | 'fail' | 'abort' | 'next' | 'handled';\n\nexport class FlowControl extends Error {\n constructor(public readonly type: FlowControlType, public readonly output: any) {\n super();\n }\n\n static respond<T>(output: T): never {\n throw new FlowControl('respond', output);\n }\n\n static next(): never {\n throw new FlowControl('next', null);\n }\n\n static handled(): never {\n throw new FlowControl('handled', null);\n }\n\n static fail(error: Error): never {\n throw new FlowControl('fail', { error: error.message });\n }\n\n static abort(reason: string): never {\n throw new FlowControl('abort', reason);\n }\n}\n\n// 1) The actual abstract class (value)\nexport abstract class FlowBase<N extends FlowName = FlowName> {\n protected input: FlowInputOf<N>;\n state: FlowStateOf<N> = FlowState.create({});\n scopeLogger: FrontMcpLogger;\n\n constructor(\n protected readonly metadata: FlowMetadata<N>,\n readonly rawInput: Partial<FlowInputOf<N>> | any,\n protected readonly scope: ScopeEntry,\n protected readonly appendContextHooks: (hooks: HookEntry[]) => void,\n protected readonly deps: ReadonlyMap<Token, unknown> = new Map(),\n ) {\n this.input = (metadata.inputSchema as any)?.parse?.(rawInput);\n this.scopeLogger = scope.logger;\n }\n\n get<T>(token: Token<T>): T {\n if (this.deps.has(token)) return this.deps.get(token) as T;\n return this.scope.providers.get(token);\n }\n\n respond(output: FlowOutputOf<N>) {\n throw FlowControl.respond((this.metadata.outputSchema as z.ZodObject<any>).parse(output));\n }\n\n fail(error: Error) {\n throw FlowControl.fail(error);\n }\n\n protected abort(message: string) {\n throw FlowControl.abort(message);\n }\n\n protected next() {\n throw FlowControl.next();\n }\n\n protected handled() {\n throw FlowControl.handled();\n }\n}\n\nexport type FlowType<Provide = FlowBase<any>> = Type<Provide>;\n"]}
1
+ {"version":3,"file":"flow.interface.js","sourceRoot":"","sources":["../../../../src/common/interfaces/flow.interface.ts"],"names":[],"mappings":"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","sourcesContent":["import { Token, Type } from './base.interface';\nimport { FlowMetadata, FlowName } from '../metadata';\nimport { z } from 'zod';\nimport { HookEntry, ScopeEntry } from '../entries';\nimport { FlowState, FlowStateOf } from './internal/flow.utils';\nimport { FrontMcpLogger } from './logger.interface';\nimport type { FrontMcpContext } from '../../context/frontmcp-context';\nimport { FrontMcpContextStorage } from '../../context/frontmcp-context-storage';\n\nexport type FlowInputOf<N extends FlowName> = z.infer<ExtendFlows[N]['input']>;\nexport type FlowOutputOf<N extends FlowName> = z.infer<ExtendFlows[N]['output']>;\nexport type FlowPlanOf<N extends FlowName> = ExtendFlows[N]['plan'];\nexport type FlowCtxOf<N extends FlowName> = ExtendFlows[N]['ctx'];\nexport type FlowStagesOf<N extends FlowName> = ExtendFlows[N]['stage'];\nexport type FlowExecuteStagesOf<N extends FlowName> = ExtendFlows[N]['executeStage'];\n\nexport type FlowControlType = 'respond' | 'fail' | 'abort' | 'next' | 'handled';\n\nexport class FlowControl extends Error {\n constructor(public readonly type: FlowControlType, public readonly output: any) {\n super();\n }\n\n static respond<T>(output: T): never {\n throw new FlowControl('respond', output);\n }\n\n static next(): never {\n throw new FlowControl('next', null);\n }\n\n static handled(): never {\n throw new FlowControl('handled', null);\n }\n\n static fail(error: Error): never {\n throw new FlowControl('fail', { error: error.message });\n }\n\n static abort(reason: string): never {\n throw new FlowControl('abort', reason);\n }\n}\n\n// 1) The actual abstract class (value)\nexport abstract class FlowBase<N extends FlowName = FlowName> {\n protected input: FlowInputOf<N>;\n state: FlowStateOf<N> = FlowState.create({});\n scopeLogger: FrontMcpLogger;\n\n constructor(\n protected readonly metadata: FlowMetadata<N>,\n readonly rawInput: Partial<FlowInputOf<N>> | any,\n protected readonly scope: ScopeEntry,\n protected readonly appendContextHooks: (hooks: HookEntry[]) => void,\n protected readonly deps: ReadonlyMap<Token, unknown> = new Map(),\n ) {\n this.input = (metadata.inputSchema as any)?.parse?.(rawInput);\n this.scopeLogger = scope.logger;\n }\n\n get<T>(token: Token<T>): T {\n if (this.deps.has(token)) return this.deps.get(token) as T;\n return this.scope.providers.get(token);\n }\n\n respond(output: FlowOutputOf<N>) {\n throw FlowControl.respond((this.metadata.outputSchema as z.ZodObject<any>).parse(output));\n }\n\n fail(error: Error) {\n throw FlowControl.fail(error);\n }\n\n protected abort(message: string) {\n throw FlowControl.abort(message);\n }\n\n protected next() {\n throw FlowControl.next();\n }\n\n protected handled() {\n throw FlowControl.handled();\n }\n\n /**\n * Get the current FrontMcpContext from AsyncLocalStorage.\n * Available in all stages after context initialization.\n *\n * @throws Error if not in a context scope\n */\n protected get context(): FrontMcpContext {\n const storage = this.scope.providers.get(FrontMcpContextStorage);\n return storage.getStoreOrThrow();\n }\n\n /**\n * Safely try to get FrontMcpContext (returns undefined if not available).\n * Use this when context might not be available (e.g., non-HTTP flows).\n */\n protected tryGetContext(): FrontMcpContext | undefined {\n try {\n const storage = this.scope.providers.get(FrontMcpContextStorage);\n return storage.getStore();\n } catch {\n return undefined;\n }\n }\n}\n\nexport type FlowType<Provide = FlowBase<any>> = Type<Provide>;\n"]}