@frontmcp/sdk 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (226) hide show
  1. package/README.md +3 -3
  2. package/package.json +8 -19
  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 +1 -0
  28. package/src/auth/session/index.js +3 -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/ui/base-layout.d.ts +0 -8
  50. package/src/auth/ui/base-layout.js +1 -14
  51. package/src/auth/ui/base-layout.js.map +1 -1
  52. package/src/auth/ui/index.d.ts +3 -4
  53. package/src/auth/ui/index.js +10 -11
  54. package/src/auth/ui/index.js.map +1 -1
  55. package/src/auth/ui/{htmx-templates.d.ts → templates.d.ts} +5 -6
  56. package/src/auth/ui/{htmx-templates.js → templates.js} +8 -15
  57. package/src/auth/ui/templates.js.map +1 -0
  58. package/src/common/decorators/decorator-utils.js.map +1 -1
  59. package/src/common/decorators/front-mcp.decorator.js +28 -2
  60. package/src/common/decorators/front-mcp.decorator.js.map +1 -1
  61. package/src/common/index.d.ts +0 -1
  62. package/src/common/index.js +0 -1
  63. package/src/common/index.js.map +1 -1
  64. package/src/common/interfaces/adapter.interface.d.ts +6 -0
  65. package/src/common/interfaces/adapter.interface.js.map +1 -1
  66. package/src/common/interfaces/execution-context.interface.d.ts +52 -3
  67. package/src/common/interfaces/execution-context.interface.js +88 -3
  68. package/src/common/interfaces/execution-context.interface.js.map +1 -1
  69. package/src/common/interfaces/flow.interface.d.ts +13 -0
  70. package/src/common/interfaces/flow.interface.js +24 -0
  71. package/src/common/interfaces/flow.interface.js.map +1 -1
  72. package/src/common/interfaces/server.interface.d.ts +9 -0
  73. package/src/common/interfaces/server.interface.js.map +1 -1
  74. package/src/common/metadata/app.metadata.d.ts +108 -0
  75. package/src/common/metadata/front-mcp.metadata.d.ts +659 -2
  76. package/src/common/metadata/front-mcp.metadata.js +3 -1
  77. package/src/common/metadata/front-mcp.metadata.js.map +1 -1
  78. package/src/common/metadata/provider.metadata.d.ts +14 -0
  79. package/src/common/metadata/provider.metadata.js +18 -2
  80. package/src/common/metadata/provider.metadata.js.map +1 -1
  81. package/src/common/metadata/tool.metadata.d.ts +33 -1
  82. package/src/common/metadata/tool.metadata.js.map +1 -1
  83. package/src/common/migrate/auth-transport.migrate.d.ts +62 -0
  84. package/src/common/migrate/auth-transport.migrate.js +140 -0
  85. package/src/common/migrate/auth-transport.migrate.js.map +1 -0
  86. package/src/common/migrate/index.d.ts +1 -0
  87. package/src/common/migrate/index.js +6 -0
  88. package/src/common/migrate/index.js.map +1 -0
  89. package/src/common/schemas/http-output.schema.d.ts +10 -2
  90. package/src/common/schemas/index.d.ts +1 -0
  91. package/src/common/schemas/index.js +1 -0
  92. package/src/common/schemas/index.js.map +1 -1
  93. package/src/common/schemas/session-header.schema.d.ts +16 -0
  94. package/src/common/schemas/session-header.schema.js +42 -0
  95. package/src/common/schemas/session-header.schema.js.map +1 -0
  96. package/src/common/tokens/front-mcp.tokens.js +3 -1
  97. package/src/common/tokens/front-mcp.tokens.js.map +1 -1
  98. package/src/common/types/options/auth.options.d.ts +233 -3
  99. package/src/common/types/options/auth.options.js +29 -40
  100. package/src/common/types/options/auth.options.js.map +1 -1
  101. package/src/common/types/options/index.d.ts +2 -0
  102. package/src/common/types/options/index.js +2 -0
  103. package/src/common/types/options/index.js.map +1 -1
  104. package/src/common/types/options/redis.options.d.ts +22 -0
  105. package/src/common/types/options/redis.options.js +45 -0
  106. package/src/common/types/options/redis.options.js.map +1 -0
  107. package/src/common/types/options/transport.options.d.ts +84 -0
  108. package/src/common/types/options/transport.options.js +121 -0
  109. package/src/common/types/options/transport.options.js.map +1 -0
  110. package/src/completion/flows/complete.flow.d.ts +17 -2
  111. package/src/context/frontmcp-context-storage.d.ts +94 -0
  112. package/src/context/frontmcp-context-storage.js +183 -0
  113. package/src/context/frontmcp-context-storage.js.map +1 -0
  114. package/src/context/frontmcp-context.d.ts +269 -0
  115. package/src/context/frontmcp-context.js +360 -0
  116. package/src/context/frontmcp-context.js.map +1 -0
  117. package/src/context/frontmcp-context.provider.d.ts +43 -0
  118. package/src/context/frontmcp-context.provider.js +61 -0
  119. package/src/context/frontmcp-context.provider.js.map +1 -0
  120. package/src/context/index.d.ts +34 -0
  121. package/src/context/index.js +64 -0
  122. package/src/context/index.js.map +1 -0
  123. package/src/context/request-context-storage.d.ts +89 -0
  124. package/src/context/request-context-storage.js +183 -0
  125. package/src/context/request-context-storage.js.map +1 -0
  126. package/src/context/request-context.d.ts +184 -0
  127. package/src/context/request-context.js +209 -0
  128. package/src/context/request-context.js.map +1 -0
  129. package/src/context/request-context.provider.d.ts +37 -0
  130. package/src/context/request-context.provider.js +51 -0
  131. package/src/context/request-context.provider.js.map +1 -0
  132. package/src/context/session-key.provider.d.ts +45 -0
  133. package/src/context/session-key.provider.js +65 -0
  134. package/src/context/session-key.provider.js.map +1 -0
  135. package/src/context/trace-context.d.ts +43 -0
  136. package/src/context/trace-context.js +142 -0
  137. package/src/context/trace-context.js.map +1 -0
  138. package/src/errors/index.d.ts +1 -1
  139. package/src/errors/index.js +3 -1
  140. package/src/errors/index.js.map +1 -1
  141. package/src/errors/mcp.error.d.ts +7 -0
  142. package/src/errors/mcp.error.js +11 -1
  143. package/src/errors/mcp.error.js.map +1 -1
  144. package/src/flows/flow.instance.d.ts +16 -0
  145. package/src/flows/flow.instance.js +166 -80
  146. package/src/flows/flow.instance.js.map +1 -1
  147. package/src/flows/flow.registry.d.ts +5 -0
  148. package/src/flows/flow.registry.js +45 -3
  149. package/src/flows/flow.registry.js.map +1 -1
  150. package/src/front-mcp/front-mcp.d.ts +12 -0
  151. package/src/front-mcp/front-mcp.js +22 -3
  152. package/src/front-mcp/front-mcp.js.map +1 -1
  153. package/src/front-mcp/front-mcp.providers.d.ts +266 -1
  154. package/src/front-mcp/front-mcp.providers.js +2 -1
  155. package/src/front-mcp/front-mcp.providers.js.map +1 -1
  156. package/src/front-mcp/serverless-handler.d.ts +28 -0
  157. package/src/front-mcp/serverless-handler.js +61 -0
  158. package/src/front-mcp/serverless-handler.js.map +1 -0
  159. package/src/hooks/hooks.utils.d.ts +1 -1
  160. package/src/hooks/hooks.utils.js +10 -3
  161. package/src/hooks/hooks.utils.js.map +1 -1
  162. package/src/index.d.ts +8 -4
  163. package/src/index.js +20 -1
  164. package/src/index.js.map +1 -1
  165. package/src/logger/instances/instance.logger.js +0 -1
  166. package/src/logger/instances/instance.logger.js.map +1 -1
  167. package/src/logging/flows/set-level.flow.d.ts +17 -2
  168. package/src/notification/notification.service.js +5 -1
  169. package/src/notification/notification.service.js.map +1 -1
  170. package/src/prompt/flows/get-prompt.flow.d.ts +97 -2
  171. package/src/prompt/flows/prompts-list.flow.d.ts +12 -1
  172. package/src/provider/provider.registry.d.ts +97 -5
  173. package/src/provider/provider.registry.js +306 -9
  174. package/src/provider/provider.registry.js.map +1 -1
  175. package/src/provider/provider.types.d.ts +21 -3
  176. package/src/provider/provider.types.js.map +1 -1
  177. package/src/resource/flows/read-resource.flow.d.ts +22 -3
  178. package/src/resource/flows/resource-templates-list.flow.d.ts +20 -1
  179. package/src/resource/flows/resources-list.flow.d.ts +20 -1
  180. package/src/resource/flows/subscribe-resource.flow.d.ts +17 -2
  181. package/src/resource/flows/unsubscribe-resource.flow.d.ts +17 -2
  182. package/src/scope/flows/http.request.flow.js +43 -7
  183. package/src/scope/flows/http.request.flow.js.map +1 -1
  184. package/src/scope/scope.instance.js +12 -5
  185. package/src/scope/scope.instance.js.map +1 -1
  186. package/src/server/adapters/base.host.adapter.d.ts +9 -0
  187. package/src/server/adapters/base.host.adapter.js.map +1 -1
  188. package/src/server/adapters/express.host.adapter.d.ts +12 -0
  189. package/src/server/adapters/express.host.adapter.js +21 -1
  190. package/src/server/adapters/express.host.adapter.js.map +1 -1
  191. package/src/server/server.instance.d.ts +3 -0
  192. package/src/server/server.instance.js +14 -7
  193. package/src/server/server.instance.js.map +1 -1
  194. package/src/tool/flows/call-tool.flow.d.ts +118 -13
  195. package/src/tool/flows/call-tool.flow.js +240 -194
  196. package/src/tool/flows/call-tool.flow.js.map +1 -1
  197. package/src/tool/flows/tools-list.flow.d.ts +25 -11
  198. package/src/tool/flows/tools-list.flow.js +82 -31
  199. package/src/tool/flows/tools-list.flow.js.map +1 -1
  200. package/src/tool/tool.instance.d.ts +1 -4
  201. package/src/transport/adapters/transport.streamable-http.adapter.js +1 -0
  202. package/src/transport/adapters/transport.streamable-http.adapter.js.map +1 -1
  203. package/src/transport/flows/handle.sse.flow.js +9 -2
  204. package/src/transport/flows/handle.sse.flow.js.map +1 -1
  205. package/src/transport/flows/handle.streamable-http.flow.js +63 -6
  206. package/src/transport/flows/handle.streamable-http.flow.js.map +1 -1
  207. package/src/transport/mcp-handlers/complete-request.handler.d.ts +27 -1
  208. package/src/transport/mcp-handlers/get-prompt-request.handler.d.ts +52 -1
  209. package/src/transport/mcp-handlers/index.d.ts +413 -7
  210. package/src/transport/mcp-handlers/initialize-request.handler.js +12 -2
  211. package/src/transport/mcp-handlers/initialize-request.handler.js.map +1 -1
  212. package/src/transport/mcp-handlers/list-prompts-request.handler.d.ts +27 -1
  213. package/src/transport/mcp-handlers/list-resource-templates-request.handler.d.ts +32 -1
  214. package/src/transport/mcp-handlers/list-resources-request.handler.d.ts +32 -1
  215. package/src/transport/mcp-handlers/list-tools-request.handler.d.ts +30 -1
  216. package/src/transport/mcp-handlers/logging-set-level-request.handler.d.ts +20 -0
  217. package/src/transport/mcp-handlers/read-resource-request.handler.d.ts +27 -1
  218. package/src/transport/mcp-handlers/subscribe-request.handler.d.ts +20 -0
  219. package/src/transport/mcp-handlers/unsubscribe-request.handler.d.ts +20 -0
  220. package/src/transport/transport.registry.d.ts +68 -4
  221. package/src/transport/transport.registry.js +313 -11
  222. package/src/transport/transport.registry.js.map +1 -1
  223. package/src/auth/ui/htmx-templates.js.map +0 -1
  224. package/src/common/providers/session.provider.d.ts +0 -13
  225. package/src/common/providers/session.provider.js +0 -27
  226. package/src/common/providers/session.provider.js.map +0 -1
@@ -2,11 +2,10 @@
2
2
  /**
3
3
  * Auth UI Module
4
4
  *
5
- * Server-rendered UI templates for OAuth flows using HTMX
6
- * with Tailwind CSS (CDN) and Google Fonts.
5
+ * Server-rendered UI templates for OAuth flows with Tailwind CSS (CDN)
6
+ * and Google Fonts.
7
7
  *
8
8
  * No build step required - all rendering is done at runtime.
9
- * HTMX provides progressive enhancement for interactivity (~14KB).
10
9
  */
11
10
  Object.defineProperty(exports, "__esModule", { value: true });
12
11
  exports.renderToHtml = exports.buildErrorPage = exports.buildLoginPage = exports.buildToolConsentPage = exports.buildFederatedLoginPage = exports.buildIncrementalAuthPage = exports.buildConsentPage = exports.escapeHtml = exports.extraWideLayout = exports.wideLayout = exports.centeredCardLayout = exports.authLayout = exports.createLayout = exports.baseLayout = exports.DEFAULT_THEME = exports.CDN = void 0;
@@ -22,14 +21,14 @@ Object.defineProperty(exports, "wideLayout", { enumerable: true, get: function (
22
21
  Object.defineProperty(exports, "extraWideLayout", { enumerable: true, get: function () { return base_layout_1.extraWideLayout; } });
23
22
  Object.defineProperty(exports, "escapeHtml", { enumerable: true, get: function () { return base_layout_1.escapeHtml; } });
24
23
  // Template builder exports
25
- var htmx_templates_1 = require("./htmx-templates");
24
+ var templates_1 = require("./templates");
26
25
  // Template builders
27
- Object.defineProperty(exports, "buildConsentPage", { enumerable: true, get: function () { return htmx_templates_1.buildConsentPage; } });
28
- Object.defineProperty(exports, "buildIncrementalAuthPage", { enumerable: true, get: function () { return htmx_templates_1.buildIncrementalAuthPage; } });
29
- Object.defineProperty(exports, "buildFederatedLoginPage", { enumerable: true, get: function () { return htmx_templates_1.buildFederatedLoginPage; } });
30
- Object.defineProperty(exports, "buildToolConsentPage", { enumerable: true, get: function () { return htmx_templates_1.buildToolConsentPage; } });
31
- Object.defineProperty(exports, "buildLoginPage", { enumerable: true, get: function () { return htmx_templates_1.buildLoginPage; } });
32
- Object.defineProperty(exports, "buildErrorPage", { enumerable: true, get: function () { return htmx_templates_1.buildErrorPage; } });
26
+ Object.defineProperty(exports, "buildConsentPage", { enumerable: true, get: function () { return templates_1.buildConsentPage; } });
27
+ Object.defineProperty(exports, "buildIncrementalAuthPage", { enumerable: true, get: function () { return templates_1.buildIncrementalAuthPage; } });
28
+ Object.defineProperty(exports, "buildFederatedLoginPage", { enumerable: true, get: function () { return templates_1.buildFederatedLoginPage; } });
29
+ Object.defineProperty(exports, "buildToolConsentPage", { enumerable: true, get: function () { return templates_1.buildToolConsentPage; } });
30
+ Object.defineProperty(exports, "buildLoginPage", { enumerable: true, get: function () { return templates_1.buildLoginPage; } });
31
+ Object.defineProperty(exports, "buildErrorPage", { enumerable: true, get: function () { return templates_1.buildErrorPage; } });
33
32
  // Utility functions
34
- Object.defineProperty(exports, "renderToHtml", { enumerable: true, get: function () { return htmx_templates_1.renderToHtml; } });
33
+ Object.defineProperty(exports, "renderToHtml", { enumerable: true, get: function () { return templates_1.renderToHtml; } });
35
34
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/auth/ui/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAEH,sBAAsB;AACtB,6CAcuB;AAbrB,kGAAA,GAAG,OAAA;AACH,4GAAA,aAAa,OAAA;AAKb,yGAAA,UAAU,OAAA;AACV,2GAAA,YAAY,OAAA;AACZ,yGAAA,UAAU,OAAA;AACV,iHAAA,kBAAkB,OAAA;AAClB,yGAAA,UAAU,OAAA;AACV,8GAAA,eAAe,OAAA;AACf,yGAAA,UAAU,OAAA;AAGZ,2BAA2B;AAC3B,mDAc0B;AATxB,oBAAoB;AACpB,kHAAA,gBAAgB,OAAA;AAChB,0HAAA,wBAAwB,OAAA;AACxB,yHAAA,uBAAuB,OAAA;AACvB,sHAAA,oBAAoB,OAAA;AACpB,gHAAA,cAAc,OAAA;AACd,gHAAA,cAAc,OAAA;AACd,oBAAoB;AACpB,8GAAA,YAAY,OAAA","sourcesContent":["/**\n * Auth UI Module\n *\n * Server-rendered UI templates for OAuth flows using HTMX\n * with Tailwind CSS (CDN) and Google Fonts.\n *\n * No build step required - all rendering is done at runtime.\n * HTMX provides progressive enhancement for interactivity (~14KB).\n */\n\n// Base layout exports\nexport {\n CDN,\n DEFAULT_THEME,\n type ThemeColors,\n type ThemeFonts,\n type ThemeConfig,\n type BaseLayoutOptions,\n baseLayout,\n createLayout,\n authLayout,\n centeredCardLayout,\n wideLayout,\n extraWideLayout,\n escapeHtml,\n} from './base-layout';\n\n// Template builder exports\nexport {\n // Types\n type AppAuthCard,\n type ProviderCard,\n type ToolCard,\n // Template builders\n buildConsentPage,\n buildIncrementalAuthPage,\n buildFederatedLoginPage,\n buildToolConsentPage,\n buildLoginPage,\n buildErrorPage,\n // Utility functions\n renderToHtml,\n} from './htmx-templates';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/auth/ui/index.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAEH,sBAAsB;AACtB,6CAcuB;AAbrB,kGAAA,GAAG,OAAA;AACH,4GAAA,aAAa,OAAA;AAKb,yGAAA,UAAU,OAAA;AACV,2GAAA,YAAY,OAAA;AACZ,yGAAA,UAAU,OAAA;AACV,iHAAA,kBAAkB,OAAA;AAClB,yGAAA,UAAU,OAAA;AACV,8GAAA,eAAe,OAAA;AACf,yGAAA,UAAU,OAAA;AAGZ,2BAA2B;AAC3B,yCAcqB;AATnB,oBAAoB;AACpB,6GAAA,gBAAgB,OAAA;AAChB,qHAAA,wBAAwB,OAAA;AACxB,oHAAA,uBAAuB,OAAA;AACvB,iHAAA,oBAAoB,OAAA;AACpB,2GAAA,cAAc,OAAA;AACd,2GAAA,cAAc,OAAA;AACd,oBAAoB;AACpB,yGAAA,YAAY,OAAA","sourcesContent":["/**\n * Auth UI Module\n *\n * Server-rendered UI templates for OAuth flows with Tailwind CSS (CDN)\n * and Google Fonts.\n *\n * No build step required - all rendering is done at runtime.\n */\n\n// Base layout exports\nexport {\n CDN,\n DEFAULT_THEME,\n type ThemeColors,\n type ThemeFonts,\n type ThemeConfig,\n type BaseLayoutOptions,\n baseLayout,\n createLayout,\n authLayout,\n centeredCardLayout,\n wideLayout,\n extraWideLayout,\n escapeHtml,\n} from './base-layout';\n\n// Template builder exports\nexport {\n // Types\n type AppAuthCard,\n type ProviderCard,\n type ToolCard,\n // Template builders\n buildConsentPage,\n buildIncrementalAuthPage,\n buildFederatedLoginPage,\n buildToolConsentPage,\n buildLoginPage,\n buildErrorPage,\n // Utility functions\n renderToHtml,\n} from './templates';\n"]}
@@ -1,7 +1,7 @@
1
1
  /**
2
- * HTMX Template Builders for OAuth UI
2
+ * Template Builders for OAuth UI
3
3
  *
4
- * Server-side HTML rendering with HTMX for interactivity.
4
+ * Server-side HTML rendering with Tailwind CSS for OAuth authorization flows.
5
5
  * No build step required - pure runtime rendering with Tailwind CSS CDN.
6
6
  *
7
7
  * Features:
@@ -10,7 +10,6 @@
10
10
  * - Federated login page for multi-provider selection
11
11
  * - All pages use Tailwind CSS from CDN (no build required)
12
12
  * - Google Fonts (Inter) for modern typography
13
- * - HTMX for progressive enhancement (~14KB)
14
13
  *
15
14
  * Uses base-layout.ts for consistent HTML shell with CDN resources.
16
15
  */
@@ -68,7 +67,7 @@ export interface ToolCard {
68
67
  */
69
68
  export declare const escapeHtml: typeof baseEscapeHtml;
70
69
  /**
71
- * Build OAuth consent page with HTMX + Tailwind
70
+ * Build OAuth consent page with Tailwind
72
71
  * Shows all apps at once with Authorize/Skip buttons
73
72
  */
74
73
  export declare function buildConsentPage(params: {
@@ -79,7 +78,7 @@ export declare function buildConsentPage(params: {
79
78
  callbackPath: string;
80
79
  }): string;
81
80
  /**
82
- * Build incremental auth page (single app) with HTMX + Tailwind
81
+ * Build incremental auth page (single app) with Tailwind
83
82
  * Used when a tool requires authorization for a skipped app
84
83
  */
85
84
  export declare function buildIncrementalAuthPage(params: {
@@ -128,7 +127,7 @@ export declare function buildErrorPage(params: {
128
127
  }): string;
129
128
  /**
130
129
  * Simple wrapper for compatibility - just returns the HTML string
131
- * (HTMX templates are already complete HTML documents)
130
+ * (Templates are already complete HTML documents)
132
131
  */
133
132
  export declare function renderToHtml(html: string, _options?: {
134
133
  title?: string;
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  /**
3
- * HTMX Template Builders for OAuth UI
3
+ * Template Builders for OAuth UI
4
4
  *
5
- * Server-side HTML rendering with HTMX for interactivity.
5
+ * Server-side HTML rendering with Tailwind CSS for OAuth authorization flows.
6
6
  * No build step required - pure runtime rendering with Tailwind CSS CDN.
7
7
  *
8
8
  * Features:
@@ -11,7 +11,6 @@
11
11
  * - Federated login page for multi-provider selection
12
12
  * - All pages use Tailwind CSS from CDN (no build required)
13
13
  * - Google Fonts (Inter) for modern typography
14
- * - HTMX for progressive enhancement (~14KB)
15
14
  *
16
15
  * Uses base-layout.ts for consistent HTML shell with CDN resources.
17
16
  */
@@ -37,7 +36,7 @@ exports.escapeHtml = base_layout_1.escapeHtml;
37
36
  // Template Builders
38
37
  // ============================================
39
38
  /**
40
- * Build OAuth consent page with HTMX + Tailwind
39
+ * Build OAuth consent page with Tailwind
41
40
  * Shows all apps at once with Authorize/Skip buttons
42
41
  */
43
42
  function buildConsentPage(params) {
@@ -92,24 +91,18 @@ function buildAppCardHtml(app, pendingAuthId, csrfToken, callbackPath) {
92
91
  <input type="hidden" name="pending_auth_id" value="${(0, exports.escapeHtml)(pendingAuthId)}">
93
92
  <input type="hidden" name="app" value="${(0, exports.escapeHtml)(app.appId)}">
94
93
  <button type="submit" name="action" value="authorize"
95
- class="flex-1 bg-blue-600 hover:bg-blue-700 text-white font-medium py-2.5 px-4 rounded-lg transition-colors"
96
- hx-post="${(0, exports.escapeHtml)(callbackPath)}"
97
- hx-swap="outerHTML"
98
- hx-target="closest div[data-app-id]">
94
+ class="flex-1 bg-blue-600 hover:bg-blue-700 text-white font-medium py-2.5 px-4 rounded-lg transition-colors">
99
95
  Authorize
100
96
  </button>
101
97
  <button type="submit" name="action" value="skip"
102
- class="px-4 py-2.5 text-gray-600 hover:text-gray-900 hover:bg-gray-100 font-medium rounded-lg transition-colors"
103
- hx-post="${(0, exports.escapeHtml)(callbackPath)}"
104
- hx-swap="outerHTML"
105
- hx-target="closest div[data-app-id]">
98
+ class="px-4 py-2.5 text-gray-600 hover:text-gray-900 hover:bg-gray-100 font-medium rounded-lg transition-colors">
106
99
  Skip
107
100
  </button>
108
101
  </form>
109
102
  </div>`;
110
103
  }
111
104
  /**
112
- * Build incremental auth page (single app) with HTMX + Tailwind
105
+ * Build incremental auth page (single app) with Tailwind
113
106
  * Used when a tool requires authorization for a skipped app
114
107
  */
115
108
  function buildIncrementalAuthPage(params) {
@@ -425,9 +418,9 @@ function buildErrorPage(params) {
425
418
  // ============================================
426
419
  /**
427
420
  * Simple wrapper for compatibility - just returns the HTML string
428
- * (HTMX templates are already complete HTML documents)
421
+ * (Templates are already complete HTML documents)
429
422
  */
430
423
  function renderToHtml(html, _options) {
431
424
  return html;
432
425
  }
433
- //# sourceMappingURL=htmx-templates.js.map
426
+ //# sourceMappingURL=templates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../../src/auth/ui/templates.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;AAkFH,4CA0BC;AAiED,4DA6DC;AAKD,0DAwFC;AAKD,oDAwHC;AAKD,wCAuDC;AAKD,wCAsBC;AAUD,oCAEC;AAriBD,+CAMuB;AAwDvB,+CAA+C;AAC/C,oBAAoB;AACpB,+CAA+C;AAE/C;;;GAGG;AACU,QAAA,UAAU,GAAG,wBAAc,CAAC;AAEzC,+CAA+C;AAC/C,oBAAoB;AACpB,+CAA+C;AAE/C;;;GAGG;AACH,SAAgB,gBAAgB,CAAC,MAMhC;IACC,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;IAE5E,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,gBAAgB,CAAC,GAAG,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAE7G,MAAM,OAAO,GAAG;kEACgD,IAAA,kBAAU,EAAC,UAAU,CAAC;;;;;;QAMhF,QAAQ;;;;;WAKL,CAAC;IAEV,OAAO,IAAA,wBAAU,EAAC,OAAO,EAAE,EAAE,KAAK,EAAE,aAAa,UAAU,EAAE,EAAE,CAAC,CAAC;AACnE,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CAAC,GAAgB,EAAE,aAAqB,EAAE,SAAiB,EAAE,YAAoB;IACxG,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO;QACtB,CAAC,CAAC,aAAa,IAAA,kBAAU,EAAC,GAAG,CAAC,OAAO,CAAC,UAAU,IAAA,kBAAU,EACtD,GAAG,CAAC,OAAO,CACZ,8CAA8C;QACjD,CAAC,CAAC,iJAAiJ,IAAA,kBAAU,EACzJ,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CACpC,QAAQ,CAAC;IAEd,MAAM,WAAW,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,oCAAoC,IAAA,kBAAU,EAAC,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAEjH,MAAM,MAAM,GAAG,GAAG,CAAC,cAAc,EAAE,MAAM;QACvC,CAAC,CAAC;;;YAGM,GAAG,CAAC,cAAc;aACjB,GAAG,CACF,CAAC,KAAK,EAAE,EAAE,CACR,mHAAmH,IAAA,kBAAU,EAC3H,KAAK,CACN,SAAS,CACb;aACA,IAAI,CAAC,EAAE,CAAC;;aAER;QACT,CAAC,CAAC,EAAE,CAAC;IAEP,OAAO,wHAAwH,IAAA,kBAAU,EACvI,GAAG,CAAC,KAAK,CACV;;QAEK,IAAI;;kDAEsC,IAAA,kBAAU,EAAC,GAAG,CAAC,OAAO,CAAC;UAC/D,WAAW;;;;MAIf,MAAM;;kCAEsB,IAAA,kBAAU,EAAC,YAAY,CAAC;gDACV,IAAA,kBAAU,EAAC,SAAS,CAAC;2DACV,IAAA,kBAAU,EAAC,aAAa,CAAC;+CACrC,IAAA,kBAAU,EAAC,GAAG,CAAC,KAAK,CAAC;;;;;;;;;;SAU3D,CAAC;AACV,CAAC;AAED;;;GAGG;AACH,SAAgB,wBAAwB,CAAC,MAKxC;IACC,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;IAE1D,MAAM,WAAW,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,iCAAiC,IAAA,kBAAU,EAAC,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAE9G,MAAM,OAAO,GAAG;;;;;;;;;;;;yEAYuD,IAAA,kBAAU,EAC3E,MAAM,CACP,mCAAmC,IAAA,kBAAU,EAAC,GAAG,CAAC,OAAO,CAAC;;;;;;;YAOrD,IAAA,kBAAU,EAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;;;oDAGP,IAAA,kBAAU,EAAC,GAAG,CAAC,OAAO,CAAC;YAC/D,WAAW;;;;mCAIY,IAAA,kBAAU,EAAC,YAAY,CAAC;6DACE,IAAA,kBAAU,EAAC,WAAW,CAAC;oDAChC,IAAA,kBAAU,EAAC,GAAG,CAAC,KAAK,CAAC;;;;;;;;;;;;;;gGAcuB,IAAA,kBAAU,EAClG,GAAG,CAAC,OAAO,CACZ;WACI,CAAC;IAEV,OAAO,IAAA,gCAAkB,EAAC,OAAO,EAAE,EAAE,KAAK,EAAE,aAAa,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AAC5E,CAAC;AAED;;GAEG;AACH,SAAgB,uBAAuB,CAAC,MAMvC;IACC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;IAEjF,MAAM,aAAa,GAAG,SAAS;SAC5B,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;QAChB,MAAM,cAAc,GAAG,QAAQ,CAAC,SAAS;YACvC,CAAC,CAAC,kGAAkG;YACpG,CAAC,CAAC,EAAE,CAAC;QAEP,MAAM,WAAW,GAAG,QAAQ,CAAC,WAAW;YACtC,CAAC,CAAC,uDAAuD,IAAA,kBAAU,EAAC,QAAQ,CAAC,WAAW,CAAC,MAAM;YAC/F,CAAC,CAAC,EAAE,CAAC;QAEP,MAAM,MAAM,GACV,QAAQ,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;YACxB,CAAC,CAAC,+CAA+C,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAA,kBAAU,EAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM;YAC7G,CAAC,CAAC,EAAE,CAAC;QAET,OAAO;uDAC0C,IAAA,kBAAU,EAAC,QAAQ,CAAC,UAAU,CAAC;uDAC/B,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE;;;sDAGpC,IAAA,kBAAU,EAAC,QAAQ,CAAC,YAAY,CAAC;YAC3E,cAAc;;iDAEuB,IAAA,kBAAU,EAAC,QAAQ,CAAC,IAAI,CAAC;UAChE,WAAW;UACX,MAAM;;aAEH,CAAC;IACV,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,OAAO,GAAG;;;QAGV,IAAA,kBAAU,EAAC,UAAU,CAAC;;;iCAGG,IAAA,kBAAU,EAAC,YAAY,CAAC;2DACE,IAAA,kBAAU,EAAC,aAAa,CAAC;;;;;;;;;;;;UAY1E,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;WA0BZ,CAAC;IAEV,OAAO,IAAA,wBAAU,EAAC,OAAO,EAAE,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED;;GAEG;AACH,SAAgB,oBAAoB,CAAC,MAQpC;IACC,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IAElG,qBAAqB;IACrB,MAAM,UAAU,GAA2D,EAAE,CAAC;IAC9E,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;QAChE,CAAC;QACD,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;IAED,MAAM,QAAQ,GACZ,QAAQ,IAAI,SAAS;QACnB,CAAC,CAAC;;kDAE0C,IAAA,kBAAU,EAAC,QAAQ,IAAI,SAAS,IAAI,EAAE,CAAC;aAC5E;QACP,CAAC,CAAC,EAAE,CAAC;IAET,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC;SACzC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE;QAC7C,MAAM,SAAS,GAAG,QAAQ;aACvB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACZ,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW;gBAC3B,CAAC,CAAC,2CAA2C,IAAA,kBAAU,EAAC,IAAI,CAAC,WAAW,CAAC,MAAM;gBAC/E,CAAC,CAAC,EAAE,CAAC;YACP,OAAO;qDACoC,IAAA,kBAAU,EACrD,IAAI,CAAC,MAAM,CACZ;;oDAE2C,IAAA,kBAAU,EAAC,IAAI,CAAC,QAAQ,CAAC;YACjE,IAAI;;eAED,CAAC;QACR,CAAC,CAAC;aACD,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,OAAO;;;;cAIC,IAAA,kBAAU,EAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;;sDAEH,IAAA,kBAAU,EAAC,OAAO,CAAC;;;;;;;6CAO5B,IAAA,kBAAU,EAAC,KAAK,CAAC;UACpD,SAAS;;WAER,CAAC;IACR,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,iBAAiB,GAAG;;;;;;;;;YAShB,CAAC;IAEX,MAAM,OAAO,GAAG;;;2BAGS,IAAA,kBAAU,EAAC,UAAU,CAAC;;;MAG3C,QAAQ;;kCAEoB,IAAA,kBAAU,EAAC,YAAY,CAAC;gDACV,IAAA,kBAAU,EAAC,SAAS,CAAC;2DACV,IAAA,kBAAU,EAAC,aAAa,CAAC;;;;;;;;;mEASjB,KAAK,CAAC,MAAM,OAAO,KAAK,CAAC,MAAM;;;;;UAKxF,SAAS;;;;;;;;;;;;;;;MAeb,iBAAiB,EAAE,CAAC;IAExB,OAAO,IAAA,6BAAe,EAAC,OAAO,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED;;GAEG;AACH,SAAgB,cAAc,CAAC,MAK9B;IACC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;IAElE,MAAM,UAAU,GAAG,KAAK;QACtB,CAAC,CAAC;;mCAGI,KAAK;aACF,KAAK,CAAC,GAAG,CAAC;aACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,kBAAU,EAAC,CAAC,CAAC,CAAC;aACzB,IAAI,CAAC,IAAI,CAAC,IAAI,gBACnB;aACK;QACT,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,OAAO,GAAG;;;sEAGoD,IAAA,kBAAU,EAAC,UAAU,CAAC;;QAEpF,UAAU;;mCAEiB,IAAA,kBAAU,EAAC,YAAY,CAAC;6DACE,IAAA,kBAAU,EAAC,aAAa,CAAC;;;;;;;;;;;;;;;;;;;;;;;kEAuBpB,IAAA,kBAAU,EAAC,UAAU,CAAC;WAC7E,CAAC;IAEV,OAAO,IAAA,gCAAkB,EAAC,OAAO,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;AAC3D,CAAC;AAED;;GAEG;AACH,SAAgB,cAAc,CAAC,MAA8C;IAC3E,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC;IAEtC,MAAM,OAAO,GAAG;;;;;;;;;;;;;qFAamE,IAAA,kBAAU,EAAC,KAAK,CAAC;;iCAErE,IAAA,kBAAU,EAAC,WAAW,CAAC;WAC7C,CAAC;IAEV,OAAO,IAAA,gCAAkB,EAAC,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;AACzD,CAAC;AAED,+CAA+C;AAC/C,8CAA8C;AAC9C,+CAA+C;AAE/C;;;GAGG;AACH,SAAgB,YAAY,CAAC,IAAY,EAAE,QAA6B;IACtE,OAAO,IAAI,CAAC;AACd,CAAC","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,15 @@ 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");
7
8
  /**
8
9
  * Decorator that marks a class as a FrontMcp Server and provides metadata
9
10
  */
10
11
  function FrontMcp(providedMetadata) {
11
12
  return (target) => {
12
- const { error, data: metadata } = metadata_1.frontMcpMetadataSchema.safeParse(providedMetadata);
13
+ // Apply migration for deprecated auth.transport and session configs
14
+ const migratedMetadata = (0, migrate_1.applyMigration)(providedMetadata);
15
+ const { error, data: metadata } = metadata_1.frontMcpMetadataSchema.safeParse(migratedMetadata);
13
16
  if (error) {
14
17
  if (error.format().apps) {
15
18
  throw new Error(`Invalid metadata provided to @FrontMcp { apps: [?] }: \n${JSON.stringify(error.format().apps, null, 2)}`);
@@ -27,7 +30,30 @@ function FrontMcp(providedMetadata) {
27
30
  for (const property in metadata) {
28
31
  Reflect.defineMetadata(tokens_1.FrontMcpTokens[property] ?? property, metadata[property], target);
29
32
  }
30
- if (metadata.serve) {
33
+ // Safe check for serverless mode - process.env may not exist in Cloudflare Workers
34
+ const isServerless = typeof process !== 'undefined' && process.env?.['FRONTMCP_SERVERLESS'] === '1';
35
+ if (isServerless) {
36
+ // Serverless mode: bootstrap, prepare (no listen), store handler globally
37
+ const sdk = '@frontmcp/sdk';
38
+ import(sdk)
39
+ .then(({ FrontMcpInstance, setServerlessHandler, setServerlessHandlerPromise, setServerlessHandlerError }) => {
40
+ if (!FrontMcpInstance) {
41
+ throw new Error(`${sdk} version mismatch, make sure you have the same version for all @frontmcp/* packages`);
42
+ }
43
+ const handlerPromise = FrontMcpInstance.createHandler(metadata);
44
+ setServerlessHandlerPromise(handlerPromise);
45
+ handlerPromise.then(setServerlessHandler).catch((err) => {
46
+ const e = err instanceof Error ? err : new Error(String(err));
47
+ setServerlessHandlerError(e);
48
+ console.error('[FrontMCP] Serverless initialization failed:', e);
49
+ });
50
+ })
51
+ .catch((err) => {
52
+ console.error('[FrontMCP] Failed to import @frontmcp/sdk for serverless init:', err);
53
+ });
54
+ }
55
+ else if (metadata.serve) {
56
+ // Normal mode: bootstrap and start server
31
57
  const sdk = '@frontmcp/sdk';
32
58
  import(sdk).then(({ FrontMcpInstance }) => {
33
59
  if (!FrontMcpInstance) {
@@ -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';\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 const sdk = '@frontmcp/sdk';\n import(sdk)\n .then(({ FrontMcpInstance, setServerlessHandler, setServerlessHandlerPromise, setServerlessHandlerError }) => {\n if (!FrontMcpInstance) {\n throw new Error(\n `${sdk} version mismatch, make sure you have the same version for all @frontmcp/* packages`,\n );\n }\n\n const handlerPromise = FrontMcpInstance.createHandler(metadata);\n setServerlessHandlerPromise(handlerPromise);\n handlerPromise.then(setServerlessHandler).catch((err: unknown) => {\n const e = err instanceof Error ? err : new Error(String(err));\n setServerlessHandlerError(e);\n console.error('[FrontMCP] Serverless initialization failed:', e);\n });\n })\n .catch((err: unknown) => {\n console.error('[FrontMCP] Failed to import @frontmcp/sdk for serverless init:', err);\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 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"]}
@@ -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
  /**