@frontmcp/testing 0.6.1 → 0.6.2

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 (142) hide show
  1. package/esm/fixtures/index.mjs +2377 -0
  2. package/esm/index.mjs +4768 -0
  3. package/esm/matchers/index.mjs +646 -0
  4. package/esm/package.json +127 -0
  5. package/esm/playwright/index.mjs +19 -0
  6. package/esm/setup.mjs +680 -0
  7. package/fixtures/index.js +2418 -0
  8. package/index.js +4866 -0
  9. package/jest-preset.js +3 -3
  10. package/matchers/index.js +673 -0
  11. package/package.json +51 -23
  12. package/playwright/index.js +46 -0
  13. package/setup.js +651 -0
  14. package/src/assertions/index.js +0 -18
  15. package/src/assertions/index.js.map +0 -1
  16. package/src/assertions/mcp-assertions.js +0 -220
  17. package/src/assertions/mcp-assertions.js.map +0 -1
  18. package/src/auth/auth-headers.js +0 -62
  19. package/src/auth/auth-headers.js.map +0 -1
  20. package/src/auth/index.js +0 -15
  21. package/src/auth/index.js.map +0 -1
  22. package/src/auth/mock-api-server.js +0 -200
  23. package/src/auth/mock-api-server.js.map +0 -1
  24. package/src/auth/mock-oauth-server.js +0 -253
  25. package/src/auth/mock-oauth-server.js.map +0 -1
  26. package/src/auth/token-factory.js +0 -181
  27. package/src/auth/token-factory.js.map +0 -1
  28. package/src/auth/user-fixtures.js +0 -92
  29. package/src/auth/user-fixtures.js.map +0 -1
  30. package/src/client/index.js +0 -12
  31. package/src/client/index.js.map +0 -1
  32. package/src/client/mcp-test-client.builder.js +0 -163
  33. package/src/client/mcp-test-client.builder.js.map +0 -1
  34. package/src/client/mcp-test-client.js +0 -937
  35. package/src/client/mcp-test-client.js.map +0 -1
  36. package/src/client/mcp-test-client.types.js +0 -16
  37. package/src/client/mcp-test-client.types.js.map +0 -1
  38. package/src/errors/index.js +0 -85
  39. package/src/errors/index.js.map +0 -1
  40. package/src/example-tools/index.js +0 -40
  41. package/src/example-tools/index.js.map +0 -1
  42. package/src/example-tools/tool-configs.js +0 -222
  43. package/src/example-tools/tool-configs.js.map +0 -1
  44. package/src/expect.js +0 -31
  45. package/src/expect.js.map +0 -1
  46. package/src/fixtures/fixture-types.js +0 -7
  47. package/src/fixtures/fixture-types.js.map +0 -1
  48. package/src/fixtures/index.js +0 -16
  49. package/src/fixtures/index.js.map +0 -1
  50. package/src/fixtures/test-fixture.js +0 -311
  51. package/src/fixtures/test-fixture.js.map +0 -1
  52. package/src/http-mock/http-mock.js +0 -544
  53. package/src/http-mock/http-mock.js.map +0 -1
  54. package/src/http-mock/http-mock.types.js +0 -10
  55. package/src/http-mock/http-mock.types.js.map +0 -1
  56. package/src/http-mock/index.js +0 -11
  57. package/src/http-mock/index.js.map +0 -1
  58. package/src/index.js +0 -167
  59. package/src/index.js.map +0 -1
  60. package/src/interceptor/index.js +0 -15
  61. package/src/interceptor/index.js.map +0 -1
  62. package/src/interceptor/interceptor-chain.js +0 -207
  63. package/src/interceptor/interceptor-chain.js.map +0 -1
  64. package/src/interceptor/interceptor.types.js +0 -7
  65. package/src/interceptor/interceptor.types.js.map +0 -1
  66. package/src/interceptor/mock-registry.js +0 -189
  67. package/src/interceptor/mock-registry.js.map +0 -1
  68. package/src/matchers/index.js +0 -12
  69. package/src/matchers/index.js.map +0 -1
  70. package/src/matchers/matcher-types.js +0 -10
  71. package/src/matchers/matcher-types.js.map +0 -1
  72. package/src/matchers/mcp-matchers.js +0 -395
  73. package/src/matchers/mcp-matchers.js.map +0 -1
  74. package/src/platform/index.js +0 -47
  75. package/src/platform/index.js.map +0 -1
  76. package/src/platform/platform-client-info.js +0 -155
  77. package/src/platform/platform-client-info.js.map +0 -1
  78. package/src/platform/platform-types.js +0 -110
  79. package/src/platform/platform-types.js.map +0 -1
  80. package/src/playwright/index.js +0 -49
  81. package/src/playwright/index.js.map +0 -1
  82. package/src/server/index.js +0 -10
  83. package/src/server/index.js.map +0 -1
  84. package/src/server/test-server.js +0 -341
  85. package/src/server/test-server.js.map +0 -1
  86. package/src/setup.js +0 -30
  87. package/src/setup.js.map +0 -1
  88. package/src/transport/index.js +0 -10
  89. package/src/transport/index.js.map +0 -1
  90. package/src/transport/streamable-http.transport.js +0 -438
  91. package/src/transport/streamable-http.transport.js.map +0 -1
  92. package/src/transport/transport.interface.js +0 -7
  93. package/src/transport/transport.interface.js.map +0 -1
  94. package/src/ui/index.js +0 -23
  95. package/src/ui/index.js.map +0 -1
  96. package/src/ui/ui-assertions.js +0 -367
  97. package/src/ui/ui-assertions.js.map +0 -1
  98. package/src/ui/ui-matchers.js +0 -493
  99. package/src/ui/ui-matchers.js.map +0 -1
  100. /package/{src/assertions → assertions}/index.d.ts +0 -0
  101. /package/{src/assertions → assertions}/mcp-assertions.d.ts +0 -0
  102. /package/{src/auth → auth}/auth-headers.d.ts +0 -0
  103. /package/{src/auth → auth}/index.d.ts +0 -0
  104. /package/{src/auth → auth}/mock-api-server.d.ts +0 -0
  105. /package/{src/auth → auth}/mock-oauth-server.d.ts +0 -0
  106. /package/{src/auth → auth}/token-factory.d.ts +0 -0
  107. /package/{src/auth → auth}/user-fixtures.d.ts +0 -0
  108. /package/{src/client → client}/index.d.ts +0 -0
  109. /package/{src/client → client}/mcp-test-client.builder.d.ts +0 -0
  110. /package/{src/client → client}/mcp-test-client.d.ts +0 -0
  111. /package/{src/client → client}/mcp-test-client.types.d.ts +0 -0
  112. /package/{src/errors → errors}/index.d.ts +0 -0
  113. /package/{src/example-tools → example-tools}/index.d.ts +0 -0
  114. /package/{src/example-tools → example-tools}/tool-configs.d.ts +0 -0
  115. /package/{src/expect.d.ts → expect.d.ts} +0 -0
  116. /package/{src/fixtures → fixtures}/fixture-types.d.ts +0 -0
  117. /package/{src/fixtures → fixtures}/index.d.ts +0 -0
  118. /package/{src/fixtures → fixtures}/test-fixture.d.ts +0 -0
  119. /package/{src/http-mock → http-mock}/http-mock.d.ts +0 -0
  120. /package/{src/http-mock → http-mock}/http-mock.types.d.ts +0 -0
  121. /package/{src/http-mock → http-mock}/index.d.ts +0 -0
  122. /package/{src/index.d.ts → index.d.ts} +0 -0
  123. /package/{src/interceptor → interceptor}/index.d.ts +0 -0
  124. /package/{src/interceptor → interceptor}/interceptor-chain.d.ts +0 -0
  125. /package/{src/interceptor → interceptor}/interceptor.types.d.ts +0 -0
  126. /package/{src/interceptor → interceptor}/mock-registry.d.ts +0 -0
  127. /package/{src/matchers → matchers}/index.d.ts +0 -0
  128. /package/{src/matchers → matchers}/matcher-types.d.ts +0 -0
  129. /package/{src/matchers → matchers}/mcp-matchers.d.ts +0 -0
  130. /package/{src/platform → platform}/index.d.ts +0 -0
  131. /package/{src/platform → platform}/platform-client-info.d.ts +0 -0
  132. /package/{src/platform → platform}/platform-types.d.ts +0 -0
  133. /package/{src/playwright → playwright}/index.d.ts +0 -0
  134. /package/{src/server → server}/index.d.ts +0 -0
  135. /package/{src/server → server}/test-server.d.ts +0 -0
  136. /package/{src/setup.d.ts → setup.d.ts} +0 -0
  137. /package/{src/transport → transport}/index.d.ts +0 -0
  138. /package/{src/transport → transport}/streamable-http.transport.d.ts +0 -0
  139. /package/{src/transport → transport}/transport.interface.d.ts +0 -0
  140. /package/{src/ui → ui}/index.d.ts +0 -0
  141. /package/{src/ui → ui}/ui-assertions.d.ts +0 -0
  142. /package/{src/ui → ui}/ui-matchers.d.ts +0 -0
package/src/index.js DELETED
@@ -1,167 +0,0 @@
1
- "use strict";
2
- /**
3
- * @file index.ts
4
- * @description Main barrel exports for @frontmcp/testing
5
- *
6
- * @example Quick Start with Fixtures
7
- * ```typescript
8
- * import { test, expect } from '@frontmcp/testing';
9
- *
10
- * test.use({
11
- * server: './src/main.ts',
12
- * port: 3003,
13
- * });
14
- *
15
- * test('server exposes tools', async ({ mcp }) => {
16
- * const tools = await mcp.tools.list();
17
- * expect(tools).toContainTool('my-tool');
18
- * });
19
- *
20
- * test('tool execution works', async ({ mcp }) => {
21
- * const result = await mcp.tools.call('my-tool', { input: 'test' });
22
- * expect(result).toBeSuccessful();
23
- * });
24
- * ```
25
- *
26
- * @example Manual Client Usage
27
- * ```typescript
28
- * import { McpTestClient, TestServer } from '@frontmcp/testing';
29
- *
30
- * const server = await TestServer.start({ command: 'npx tsx src/main.ts' });
31
- * const client = await McpTestClient.create({ baseUrl: server.info.baseUrl })
32
- * .withTransport('streamable-http')
33
- * .buildAndConnect();
34
- *
35
- * const tools = await client.tools.list();
36
- * console.log(tools);
37
- *
38
- * await client.disconnect();
39
- * await server.stop();
40
- * ```
41
- */
42
- Object.defineProperty(exports, "__esModule", { value: true });
43
- exports.FULL_UI_TOOL_CONFIG = exports.BASIC_UI_TOOL_CONFIG = exports.PLATFORM_DETECTION_PATTERNS = exports.getPlatformUserAgent = exports.buildUserAgent = exports.getPlatformClientInfo = exports.getForbiddenMetaPrefixes = exports.getToolCallMetaPrefixes = exports.getToolsListMetaPrefixes = exports.isFrontmcpPlatform = exports.isExtAppsPlatform = exports.isOpenAIPlatform = exports.getPlatformMimeType = exports.getPlatformMetaNamespace = exports.UIAssertions = exports.uiMatchers = exports.httpResponse = exports.httpMock = exports.interceptors = exports.mockResponse = exports.DefaultInterceptorChain = exports.DefaultMockRegistry = exports.mcpMatchers = exports.expect = exports.test = exports.AssertionError = exports.ServerStartError = exports.McpProtocolError = exports.TimeoutError = exports.ConnectionError = exports.TestClientError = exports.hasMimeType = exports.hasTextContent = exports.isError = exports.isSuccessful = exports.containsPrompt = exports.containsResourceTemplate = exports.containsResource = exports.containsTool = exports.McpAssertions = exports.TestServer = exports.MockAPIServer = exports.MockOAuthServer = exports.createTestUser = exports.TestUsers = exports.AuthHeaders = exports.TestTokenFactory = exports.StreamableHttpTransport = exports.McpTestClientBuilder = exports.McpTestClient = void 0;
44
- exports.EXPECTED_FRONTMCP_TOOL_CALL_META_KEYS = exports.EXPECTED_FRONTMCP_TOOLS_LIST_META_KEYS = exports.EXPECTED_EXTAPPS_TOOL_CALL_META_KEYS = exports.EXPECTED_EXTAPPS_TOOLS_LIST_META_KEYS = exports.EXPECTED_OPENAI_TOOL_CALL_META_KEYS = exports.EXPECTED_OPENAI_TOOLS_LIST_META_KEYS = exports.generateFullUIToolOutput = exports.generateBasicUIToolOutput = exports.fullUIToolOutputSchema = exports.fullUIToolInputSchema = exports.basicUIToolOutputSchema = exports.basicUIToolInputSchema = void 0;
45
- // ═══════════════════════════════════════════════════════════════════
46
- // CLIENT
47
- // ═══════════════════════════════════════════════════════════════════
48
- var mcp_test_client_1 = require("./client/mcp-test-client");
49
- Object.defineProperty(exports, "McpTestClient", { enumerable: true, get: function () { return mcp_test_client_1.McpTestClient; } });
50
- var mcp_test_client_builder_1 = require("./client/mcp-test-client.builder");
51
- Object.defineProperty(exports, "McpTestClientBuilder", { enumerable: true, get: function () { return mcp_test_client_builder_1.McpTestClientBuilder; } });
52
- var streamable_http_transport_1 = require("./transport/streamable-http.transport");
53
- Object.defineProperty(exports, "StreamableHttpTransport", { enumerable: true, get: function () { return streamable_http_transport_1.StreamableHttpTransport; } });
54
- // ═══════════════════════════════════════════════════════════════════
55
- // AUTH
56
- // ═══════════════════════════════════════════════════════════════════
57
- var token_factory_1 = require("./auth/token-factory");
58
- Object.defineProperty(exports, "TestTokenFactory", { enumerable: true, get: function () { return token_factory_1.TestTokenFactory; } });
59
- var auth_headers_1 = require("./auth/auth-headers");
60
- Object.defineProperty(exports, "AuthHeaders", { enumerable: true, get: function () { return auth_headers_1.AuthHeaders; } });
61
- var user_fixtures_1 = require("./auth/user-fixtures");
62
- Object.defineProperty(exports, "TestUsers", { enumerable: true, get: function () { return user_fixtures_1.TestUsers; } });
63
- Object.defineProperty(exports, "createTestUser", { enumerable: true, get: function () { return user_fixtures_1.createTestUser; } });
64
- var mock_oauth_server_1 = require("./auth/mock-oauth-server");
65
- Object.defineProperty(exports, "MockOAuthServer", { enumerable: true, get: function () { return mock_oauth_server_1.MockOAuthServer; } });
66
- var mock_api_server_1 = require("./auth/mock-api-server");
67
- Object.defineProperty(exports, "MockAPIServer", { enumerable: true, get: function () { return mock_api_server_1.MockAPIServer; } });
68
- // ═══════════════════════════════════════════════════════════════════
69
- // SERVER
70
- // ═══════════════════════════════════════════════════════════════════
71
- var test_server_1 = require("./server/test-server");
72
- Object.defineProperty(exports, "TestServer", { enumerable: true, get: function () { return test_server_1.TestServer; } });
73
- // ═══════════════════════════════════════════════════════════════════
74
- // ASSERTIONS
75
- // ═══════════════════════════════════════════════════════════════════
76
- var mcp_assertions_1 = require("./assertions/mcp-assertions");
77
- Object.defineProperty(exports, "McpAssertions", { enumerable: true, get: function () { return mcp_assertions_1.McpAssertions; } });
78
- Object.defineProperty(exports, "containsTool", { enumerable: true, get: function () { return mcp_assertions_1.containsTool; } });
79
- Object.defineProperty(exports, "containsResource", { enumerable: true, get: function () { return mcp_assertions_1.containsResource; } });
80
- Object.defineProperty(exports, "containsResourceTemplate", { enumerable: true, get: function () { return mcp_assertions_1.containsResourceTemplate; } });
81
- Object.defineProperty(exports, "containsPrompt", { enumerable: true, get: function () { return mcp_assertions_1.containsPrompt; } });
82
- Object.defineProperty(exports, "isSuccessful", { enumerable: true, get: function () { return mcp_assertions_1.isSuccessful; } });
83
- Object.defineProperty(exports, "isError", { enumerable: true, get: function () { return mcp_assertions_1.isError; } });
84
- Object.defineProperty(exports, "hasTextContent", { enumerable: true, get: function () { return mcp_assertions_1.hasTextContent; } });
85
- Object.defineProperty(exports, "hasMimeType", { enumerable: true, get: function () { return mcp_assertions_1.hasMimeType; } });
86
- // ═══════════════════════════════════════════════════════════════════
87
- // ERRORS
88
- // ═══════════════════════════════════════════════════════════════════
89
- var index_1 = require("./errors/index");
90
- Object.defineProperty(exports, "TestClientError", { enumerable: true, get: function () { return index_1.TestClientError; } });
91
- Object.defineProperty(exports, "ConnectionError", { enumerable: true, get: function () { return index_1.ConnectionError; } });
92
- Object.defineProperty(exports, "TimeoutError", { enumerable: true, get: function () { return index_1.TimeoutError; } });
93
- Object.defineProperty(exports, "McpProtocolError", { enumerable: true, get: function () { return index_1.McpProtocolError; } });
94
- Object.defineProperty(exports, "ServerStartError", { enumerable: true, get: function () { return index_1.ServerStartError; } });
95
- Object.defineProperty(exports, "AssertionError", { enumerable: true, get: function () { return index_1.AssertionError; } });
96
- // ═══════════════════════════════════════════════════════════════════
97
- // FIXTURES (Primary API)
98
- // ═══════════════════════════════════════════════════════════════════
99
- var fixtures_1 = require("./fixtures");
100
- Object.defineProperty(exports, "test", { enumerable: true, get: function () { return fixtures_1.test; } });
101
- // ═══════════════════════════════════════════════════════════════════
102
- // EXPECT (Primary API)
103
- // ═══════════════════════════════════════════════════════════════════
104
- // Export the pre-typed expect with MCP matchers (Playwright-style approach)
105
- // This provides proper typing without relying on global namespace augmentation
106
- var expect_1 = require("./expect");
107
- Object.defineProperty(exports, "expect", { enumerable: true, get: function () { return expect_1.expect; } });
108
- // ═══════════════════════════════════════════════════════════════════
109
- // CUSTOM MATCHERS
110
- // ═══════════════════════════════════════════════════════════════════
111
- var matchers_1 = require("./matchers");
112
- Object.defineProperty(exports, "mcpMatchers", { enumerable: true, get: function () { return matchers_1.mcpMatchers; } });
113
- // ═══════════════════════════════════════════════════════════════════
114
- // INTERCEPTORS & MOCKING
115
- // ═══════════════════════════════════════════════════════════════════
116
- var interceptor_1 = require("./interceptor");
117
- Object.defineProperty(exports, "DefaultMockRegistry", { enumerable: true, get: function () { return interceptor_1.DefaultMockRegistry; } });
118
- Object.defineProperty(exports, "DefaultInterceptorChain", { enumerable: true, get: function () { return interceptor_1.DefaultInterceptorChain; } });
119
- Object.defineProperty(exports, "mockResponse", { enumerable: true, get: function () { return interceptor_1.mockResponse; } });
120
- Object.defineProperty(exports, "interceptors", { enumerable: true, get: function () { return interceptor_1.interceptors; } });
121
- // ═══════════════════════════════════════════════════════════════════
122
- // HTTP MOCKING (for offline testing)
123
- // ═══════════════════════════════════════════════════════════════════
124
- var http_mock_1 = require("./http-mock");
125
- Object.defineProperty(exports, "httpMock", { enumerable: true, get: function () { return http_mock_1.httpMock; } });
126
- Object.defineProperty(exports, "httpResponse", { enumerable: true, get: function () { return http_mock_1.httpResponse; } });
127
- // ═══════════════════════════════════════════════════════════════════
128
- // UI TESTING
129
- // ═══════════════════════════════════════════════════════════════════
130
- var ui_1 = require("./ui");
131
- Object.defineProperty(exports, "uiMatchers", { enumerable: true, get: function () { return ui_1.uiMatchers; } });
132
- Object.defineProperty(exports, "UIAssertions", { enumerable: true, get: function () { return ui_1.UIAssertions; } });
133
- var platform_1 = require("./platform");
134
- Object.defineProperty(exports, "getPlatformMetaNamespace", { enumerable: true, get: function () { return platform_1.getPlatformMetaNamespace; } });
135
- Object.defineProperty(exports, "getPlatformMimeType", { enumerable: true, get: function () { return platform_1.getPlatformMimeType; } });
136
- Object.defineProperty(exports, "isOpenAIPlatform", { enumerable: true, get: function () { return platform_1.isOpenAIPlatform; } });
137
- Object.defineProperty(exports, "isExtAppsPlatform", { enumerable: true, get: function () { return platform_1.isExtAppsPlatform; } });
138
- Object.defineProperty(exports, "isFrontmcpPlatform", { enumerable: true, get: function () { return platform_1.isFrontmcpPlatform; } });
139
- Object.defineProperty(exports, "getToolsListMetaPrefixes", { enumerable: true, get: function () { return platform_1.getToolsListMetaPrefixes; } });
140
- Object.defineProperty(exports, "getToolCallMetaPrefixes", { enumerable: true, get: function () { return platform_1.getToolCallMetaPrefixes; } });
141
- Object.defineProperty(exports, "getForbiddenMetaPrefixes", { enumerable: true, get: function () { return platform_1.getForbiddenMetaPrefixes; } });
142
- Object.defineProperty(exports, "getPlatformClientInfo", { enumerable: true, get: function () { return platform_1.getPlatformClientInfo; } });
143
- Object.defineProperty(exports, "buildUserAgent", { enumerable: true, get: function () { return platform_1.buildUserAgent; } });
144
- Object.defineProperty(exports, "getPlatformUserAgent", { enumerable: true, get: function () { return platform_1.getPlatformUserAgent; } });
145
- Object.defineProperty(exports, "PLATFORM_DETECTION_PATTERNS", { enumerable: true, get: function () { return platform_1.PLATFORM_DETECTION_PATTERNS; } });
146
- // ═══════════════════════════════════════════════════════════════════
147
- // EXAMPLE TOOLS (for E2E platform testing)
148
- // ═══════════════════════════════════════════════════════════════════
149
- var example_tools_1 = require("./example-tools");
150
- // Tool configurations
151
- Object.defineProperty(exports, "BASIC_UI_TOOL_CONFIG", { enumerable: true, get: function () { return example_tools_1.BASIC_UI_TOOL_CONFIG; } });
152
- Object.defineProperty(exports, "FULL_UI_TOOL_CONFIG", { enumerable: true, get: function () { return example_tools_1.FULL_UI_TOOL_CONFIG; } });
153
- Object.defineProperty(exports, "basicUIToolInputSchema", { enumerable: true, get: function () { return example_tools_1.basicUIToolInputSchema; } });
154
- Object.defineProperty(exports, "basicUIToolOutputSchema", { enumerable: true, get: function () { return example_tools_1.basicUIToolOutputSchema; } });
155
- Object.defineProperty(exports, "fullUIToolInputSchema", { enumerable: true, get: function () { return example_tools_1.fullUIToolInputSchema; } });
156
- Object.defineProperty(exports, "fullUIToolOutputSchema", { enumerable: true, get: function () { return example_tools_1.fullUIToolOutputSchema; } });
157
- // Execution helpers
158
- Object.defineProperty(exports, "generateBasicUIToolOutput", { enumerable: true, get: function () { return example_tools_1.generateBasicUIToolOutput; } });
159
- Object.defineProperty(exports, "generateFullUIToolOutput", { enumerable: true, get: function () { return example_tools_1.generateFullUIToolOutput; } });
160
- // Expected meta keys
161
- Object.defineProperty(exports, "EXPECTED_OPENAI_TOOLS_LIST_META_KEYS", { enumerable: true, get: function () { return example_tools_1.EXPECTED_OPENAI_TOOLS_LIST_META_KEYS; } });
162
- Object.defineProperty(exports, "EXPECTED_OPENAI_TOOL_CALL_META_KEYS", { enumerable: true, get: function () { return example_tools_1.EXPECTED_OPENAI_TOOL_CALL_META_KEYS; } });
163
- Object.defineProperty(exports, "EXPECTED_EXTAPPS_TOOLS_LIST_META_KEYS", { enumerable: true, get: function () { return example_tools_1.EXPECTED_EXTAPPS_TOOLS_LIST_META_KEYS; } });
164
- Object.defineProperty(exports, "EXPECTED_EXTAPPS_TOOL_CALL_META_KEYS", { enumerable: true, get: function () { return example_tools_1.EXPECTED_EXTAPPS_TOOL_CALL_META_KEYS; } });
165
- Object.defineProperty(exports, "EXPECTED_FRONTMCP_TOOLS_LIST_META_KEYS", { enumerable: true, get: function () { return example_tools_1.EXPECTED_FRONTMCP_TOOLS_LIST_META_KEYS; } });
166
- Object.defineProperty(exports, "EXPECTED_FRONTMCP_TOOL_CALL_META_KEYS", { enumerable: true, get: function () { return example_tools_1.EXPECTED_FRONTMCP_TOOL_CALL_META_KEYS; } });
167
- //# sourceMappingURL=index.js.map
package/src/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @file index.ts\n * @description Main barrel exports for @frontmcp/testing\n *\n * @example Quick Start with Fixtures\n * ```typescript\n * import { test, expect } from '@frontmcp/testing';\n *\n * test.use({\n * server: './src/main.ts',\n * port: 3003,\n * });\n *\n * test('server exposes tools', async ({ mcp }) => {\n * const tools = await mcp.tools.list();\n * expect(tools).toContainTool('my-tool');\n * });\n *\n * test('tool execution works', async ({ mcp }) => {\n * const result = await mcp.tools.call('my-tool', { input: 'test' });\n * expect(result).toBeSuccessful();\n * });\n * ```\n *\n * @example Manual Client Usage\n * ```typescript\n * import { McpTestClient, TestServer } from '@frontmcp/testing';\n *\n * const server = await TestServer.start({ command: 'npx tsx src/main.ts' });\n * const client = await McpTestClient.create({ baseUrl: server.info.baseUrl })\n * .withTransport('streamable-http')\n * .buildAndConnect();\n *\n * const tools = await client.tools.list();\n * console.log(tools);\n *\n * await client.disconnect();\n * await server.stop();\n * ```\n */\n\n// ═══════════════════════════════════════════════════════════════════\n// CLIENT\n// ═══════════════════════════════════════════════════════════════════\n\nexport { McpTestClient } from './client/mcp-test-client';\nexport { McpTestClientBuilder } from './client/mcp-test-client.builder';\nexport type {\n McpTestClientConfig,\n McpResponse,\n McpErrorInfo,\n TestTransportType,\n TestAuthConfig,\n ToolResultWrapper,\n ResourceContentWrapper,\n PromptResultWrapper,\n LogEntry,\n LogLevel,\n RequestTrace,\n NotificationEntry,\n ProgressUpdate,\n SessionInfo,\n AuthState,\n} from './client/mcp-test-client.types';\n\n// ═══════════════════════════════════════════════════════════════════\n// TRANSPORT\n// ═══════════════════════════════════════════════════════════════════\n\nexport type { McpTransport, TransportConfig, TransportState } from './transport/transport.interface';\nexport { StreamableHttpTransport } from './transport/streamable-http.transport';\n\n// ═══════════════════════════════════════════════════════════════════\n// AUTH\n// ═══════════════════════════════════════════════════════════════════\n\nexport { TestTokenFactory } from './auth/token-factory';\nexport type { CreateTokenOptions, TokenFactoryOptions } from './auth/token-factory';\nexport { AuthHeaders } from './auth/auth-headers';\nexport { TestUsers, createTestUser } from './auth/user-fixtures';\nexport type { TestUserFixture } from './auth/user-fixtures';\nexport { MockOAuthServer } from './auth/mock-oauth-server';\nexport type { MockOAuthServerOptions, MockOAuthServerInfo } from './auth/mock-oauth-server';\nexport { MockAPIServer } from './auth/mock-api-server';\nexport type { MockAPIServerOptions, MockAPIServerInfo, MockRoute, MockResponse } from './auth/mock-api-server';\n\n// ═══════════════════════════════════════════════════════════════════\n// SERVER\n// ═══════════════════════════════════════════════════════════════════\n\nexport { TestServer } from './server/test-server';\nexport type { TestServerOptions, TestServerInfo } from './server/test-server';\n\n// ═══════════════════════════════════════════════════════════════════\n// ASSERTIONS\n// ═══════════════════════════════════════════════════════════════════\n\nexport {\n McpAssertions,\n containsTool,\n containsResource,\n containsResourceTemplate,\n containsPrompt,\n isSuccessful,\n isError,\n hasTextContent,\n hasMimeType,\n} from './assertions/mcp-assertions';\n\n// ═══════════════════════════════════════════════════════════════════\n// ERRORS\n// ═══════════════════════════════════════════════════════════════════\n\nexport {\n TestClientError,\n ConnectionError,\n TimeoutError,\n McpProtocolError,\n ServerStartError,\n AssertionError,\n} from './errors/index';\n\n// ═══════════════════════════════════════════════════════════════════\n// RE-EXPORTS FROM MCP SDK\n// ═══════════════════════════════════════════════════════════════════\n\nexport type {\n InitializeResult,\n ListToolsResult,\n CallToolResult,\n ListResourcesResult,\n ReadResourceResult,\n ListResourceTemplatesResult,\n ListPromptsResult,\n GetPromptResult,\n Tool,\n Resource,\n ResourceTemplate,\n Prompt,\n // JSON-RPC types\n JSONRPCRequest,\n JSONRPCResponse,\n} from './client/mcp-test-client.types';\n\n// ═══════════════════════════════════════════════════════════════════\n// FIXTURES (Primary API)\n// ═══════════════════════════════════════════════════════════════════\n\nexport { test } from './fixtures';\nexport type {\n TestConfig,\n TestFixtures,\n AuthFixture,\n ServerFixture,\n TestFn,\n TestWithFixtures,\n TestUser,\n} from './fixtures';\n\n// ═══════════════════════════════════════════════════════════════════\n// EXPECT (Primary API)\n// ═══════════════════════════════════════════════════════════════════\n\n// Export the pre-typed expect with MCP matchers (Playwright-style approach)\n// This provides proper typing without relying on global namespace augmentation\nexport { expect } from './expect';\n\n// ═══════════════════════════════════════════════════════════════════\n// CUSTOM MATCHERS\n// ═══════════════════════════════════════════════════════════════════\n\nexport { mcpMatchers } from './matchers';\nexport type { McpMatchers } from './matchers';\n\n// ═══════════════════════════════════════════════════════════════════\n// INTERCEPTORS & MOCKING\n// ═══════════════════════════════════════════════════════════════════\n\nexport { DefaultMockRegistry, DefaultInterceptorChain, mockResponse, interceptors } from './interceptor';\n\nexport type {\n InterceptorContext,\n InterceptorResult,\n RequestInterceptor,\n ResponseInterceptorContext,\n ResponseInterceptorResult,\n ResponseInterceptor,\n MockDefinition,\n MockRegistry,\n MockHandle,\n InterceptorChain,\n} from './interceptor';\n\n// ═══════════════════════════════════════════════════════════════════\n// HTTP MOCKING (for offline testing)\n// ═══════════════════════════════════════════════════════════════════\n\nexport { httpMock, httpResponse } from './http-mock';\n\nexport type {\n HttpMethod,\n HttpRequestMatcher,\n HttpMockResponse,\n HttpMockDefinition,\n HttpRequestInfo,\n HttpMockHandle,\n HttpInterceptor,\n HttpMockManager,\n} from './http-mock';\n\n// ═══════════════════════════════════════════════════════════════════\n// UI TESTING\n// ═══════════════════════════════════════════════════════════════════\n\nexport { uiMatchers, UIAssertions } from './ui';\n\n// ═══════════════════════════════════════════════════════════════════\n// PLATFORM TESTING\n// ═══════════════════════════════════════════════════════════════════\n\nexport type { TestPlatformType, PlatformMetaNamespace, TestClientInfo } from './platform';\n\nexport {\n getPlatformMetaNamespace,\n getPlatformMimeType,\n isOpenAIPlatform,\n isExtAppsPlatform,\n isFrontmcpPlatform,\n getToolsListMetaPrefixes,\n getToolCallMetaPrefixes,\n getForbiddenMetaPrefixes,\n getPlatformClientInfo,\n buildUserAgent,\n getPlatformUserAgent,\n PLATFORM_DETECTION_PATTERNS,\n} from './platform';\n\n// ═══════════════════════════════════════════════════════════════════\n// EXAMPLE TOOLS (for E2E platform testing)\n// ═══════════════════════════════════════════════════════════════════\n\nexport {\n // Tool configurations\n BASIC_UI_TOOL_CONFIG,\n FULL_UI_TOOL_CONFIG,\n basicUIToolInputSchema,\n basicUIToolOutputSchema,\n fullUIToolInputSchema,\n fullUIToolOutputSchema,\n // Execution helpers\n generateBasicUIToolOutput,\n generateFullUIToolOutput,\n // Expected meta keys\n EXPECTED_OPENAI_TOOLS_LIST_META_KEYS,\n EXPECTED_OPENAI_TOOL_CALL_META_KEYS,\n EXPECTED_EXTAPPS_TOOLS_LIST_META_KEYS,\n EXPECTED_EXTAPPS_TOOL_CALL_META_KEYS,\n EXPECTED_FRONTMCP_TOOLS_LIST_META_KEYS,\n EXPECTED_FRONTMCP_TOOL_CALL_META_KEYS,\n} from './example-tools';\n"]}
@@ -1,15 +0,0 @@
1
- "use strict";
2
- /**
3
- * @file index.ts
4
- * @description Barrel exports for interceptor module
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.interceptors = exports.DefaultInterceptorChain = exports.mockResponse = exports.DefaultMockRegistry = void 0;
8
- // Classes
9
- var mock_registry_1 = require("./mock-registry");
10
- Object.defineProperty(exports, "DefaultMockRegistry", { enumerable: true, get: function () { return mock_registry_1.DefaultMockRegistry; } });
11
- Object.defineProperty(exports, "mockResponse", { enumerable: true, get: function () { return mock_registry_1.mockResponse; } });
12
- var interceptor_chain_1 = require("./interceptor-chain");
13
- Object.defineProperty(exports, "DefaultInterceptorChain", { enumerable: true, get: function () { return interceptor_chain_1.DefaultInterceptorChain; } });
14
- Object.defineProperty(exports, "interceptors", { enumerable: true, get: function () { return interceptor_chain_1.interceptors; } });
15
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/interceptor/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAgBH,UAAU;AACV,iDAAoE;AAA3D,oHAAA,mBAAmB,OAAA;AAAE,6GAAA,YAAY,OAAA;AAC1C,yDAA4E;AAAnE,4HAAA,uBAAuB,OAAA;AAAE,iHAAA,YAAY,OAAA","sourcesContent":["/**\n * @file index.ts\n * @description Barrel exports for interceptor module\n */\n\n// Types\nexport type {\n InterceptorContext,\n InterceptorResult,\n RequestInterceptor,\n ResponseInterceptorContext,\n ResponseInterceptorResult,\n ResponseInterceptor,\n MockDefinition,\n MockRegistry,\n MockHandle,\n InterceptorChain,\n} from './interceptor.types';\n\n// Classes\nexport { DefaultMockRegistry, mockResponse } from './mock-registry';\nexport { DefaultInterceptorChain, interceptors } from './interceptor-chain';\n"]}
@@ -1,207 +0,0 @@
1
- "use strict";
2
- /**
3
- * @file interceptor-chain.ts
4
- * @description Interceptor chain for request/response interception
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.interceptors = exports.DefaultInterceptorChain = void 0;
8
- const mock_registry_1 = require("./mock-registry");
9
- /**
10
- * Default implementation of InterceptorChain
11
- */
12
- class DefaultInterceptorChain {
13
- request = [];
14
- response = [];
15
- mocks;
16
- constructor() {
17
- this.mocks = new mock_registry_1.DefaultMockRegistry();
18
- }
19
- /**
20
- * Add a request interceptor
21
- */
22
- addRequestInterceptor(interceptor) {
23
- this.request.push(interceptor);
24
- return () => {
25
- const index = this.request.indexOf(interceptor);
26
- if (index !== -1) {
27
- this.request.splice(index, 1);
28
- }
29
- };
30
- }
31
- /**
32
- * Add a response interceptor
33
- */
34
- addResponseInterceptor(interceptor) {
35
- this.response.push(interceptor);
36
- return () => {
37
- const index = this.response.indexOf(interceptor);
38
- if (index !== -1) {
39
- this.response.splice(index, 1);
40
- }
41
- };
42
- }
43
- /**
44
- * Process a request through the interceptor chain
45
- * Returns either:
46
- * - { type: 'continue', request } - continue with (possibly modified) request
47
- * - { type: 'mock', response } - return mock response immediately
48
- * - { type: 'error', error } - throw error
49
- */
50
- async processRequest(request, meta) {
51
- let currentRequest = request;
52
- // 1. Check mocks first
53
- const mockDef = this.mocks.match(request);
54
- if (mockDef) {
55
- // Apply delay if specified
56
- if (mockDef.delay && mockDef.delay > 0) {
57
- await sleep(mockDef.delay);
58
- }
59
- // Get mock response
60
- let mockResponse;
61
- if (typeof mockDef.response === 'function') {
62
- mockResponse = await mockDef.response(request);
63
- }
64
- else {
65
- mockResponse = mockDef.response;
66
- }
67
- // Ensure the response ID matches the request ID
68
- return {
69
- type: 'mock',
70
- response: { ...mockResponse, id: request.id ?? mockResponse.id },
71
- };
72
- }
73
- // 2. Run request interceptors
74
- for (const interceptor of this.request) {
75
- const ctx = {
76
- request: currentRequest,
77
- meta,
78
- };
79
- const result = await interceptor(ctx);
80
- switch (result.action) {
81
- case 'passthrough':
82
- // Continue with current request
83
- break;
84
- case 'modify':
85
- // Use modified request
86
- currentRequest = result.request;
87
- break;
88
- case 'mock':
89
- // Return mock response immediately
90
- return {
91
- type: 'mock',
92
- response: { ...result.response, id: request.id ?? result.response.id },
93
- };
94
- case 'error':
95
- return { type: 'error', error: result.error };
96
- }
97
- }
98
- return { type: 'continue', request: currentRequest };
99
- }
100
- /**
101
- * Process a response through the interceptor chain
102
- */
103
- async processResponse(request, response, durationMs) {
104
- let currentResponse = response;
105
- for (const interceptor of this.response) {
106
- const ctx = {
107
- request,
108
- response: currentResponse,
109
- durationMs,
110
- };
111
- const result = await interceptor(ctx);
112
- switch (result.action) {
113
- case 'passthrough':
114
- // Continue with current response
115
- break;
116
- case 'modify':
117
- // Use modified response
118
- currentResponse = result.response;
119
- break;
120
- }
121
- }
122
- return currentResponse;
123
- }
124
- /**
125
- * Clear all interceptors and mocks
126
- */
127
- clear() {
128
- this.request = [];
129
- this.response = [];
130
- this.mocks.clear();
131
- }
132
- }
133
- exports.DefaultInterceptorChain = DefaultInterceptorChain;
134
- /**
135
- * Sleep helper
136
- */
137
- function sleep(ms) {
138
- return new Promise((resolve) => setTimeout(resolve, ms));
139
- }
140
- /**
141
- * Convenience interceptor creators
142
- */
143
- exports.interceptors = {
144
- /**
145
- * Create an interceptor that logs all requests
146
- */
147
- logger(logFn = console.log) {
148
- return (ctx) => {
149
- logFn(`[MCP Request] ${ctx.request.method}`, ctx.request.params);
150
- return { action: 'passthrough' };
151
- };
152
- },
153
- /**
154
- * Create an interceptor that adds latency to all requests
155
- */
156
- delay(ms) {
157
- return async () => {
158
- await sleep(ms);
159
- return { action: 'passthrough' };
160
- };
161
- },
162
- /**
163
- * Create an interceptor that fails requests matching a condition
164
- */
165
- failWhen(condition, error) {
166
- return (ctx) => {
167
- if (condition(ctx)) {
168
- const err = typeof error === 'string' ? new Error(error) : error;
169
- return { action: 'error', error: err };
170
- }
171
- return { action: 'passthrough' };
172
- };
173
- },
174
- /**
175
- * Create an interceptor that modifies specific methods
176
- */
177
- modifyMethod(method, modifier) {
178
- return (ctx) => {
179
- if (ctx.request.method === method) {
180
- return { action: 'modify', request: modifier(ctx.request) };
181
- }
182
- return { action: 'passthrough' };
183
- };
184
- },
185
- /**
186
- * Create a response interceptor that logs responses
187
- */
188
- responseLogger(logFn = console.log) {
189
- return (ctx) => {
190
- const status = ctx.response.error ? 'ERROR' : 'OK';
191
- logFn(`[MCP Response] ${ctx.request.method} ${status} (${ctx.durationMs}ms)`, ctx.response);
192
- return { action: 'passthrough' };
193
- };
194
- },
195
- /**
196
- * Create a response interceptor that modifies specific responses
197
- */
198
- modifyResponse(method, modifier) {
199
- return (ctx) => {
200
- if (ctx.request.method === method) {
201
- return { action: 'modify', response: modifier(ctx.response) };
202
- }
203
- return { action: 'passthrough' };
204
- };
205
- },
206
- };
207
- //# sourceMappingURL=interceptor-chain.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"interceptor-chain.js","sourceRoot":"","sources":["../../../src/interceptor/interceptor-chain.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @file interceptor-chain.ts\n * @description Interceptor chain for request/response interception\n */\n\nimport type { JsonRpcRequest, JsonRpcResponse } from '../transport/transport.interface';\nimport type {\n InterceptorChain,\n RequestInterceptor,\n ResponseInterceptor,\n InterceptorContext,\n InterceptorResult,\n ResponseInterceptorContext,\n ResponseInterceptorResult,\n MockRegistry,\n} from './interceptor.types';\nimport { DefaultMockRegistry } from './mock-registry';\n\n/**\n * Default implementation of InterceptorChain\n */\nexport class DefaultInterceptorChain implements InterceptorChain {\n request: RequestInterceptor[] = [];\n response: ResponseInterceptor[] = [];\n mocks: MockRegistry;\n\n constructor() {\n this.mocks = new DefaultMockRegistry();\n }\n\n /**\n * Add a request interceptor\n */\n addRequestInterceptor(interceptor: RequestInterceptor): () => void {\n this.request.push(interceptor);\n return () => {\n const index = this.request.indexOf(interceptor);\n if (index !== -1) {\n this.request.splice(index, 1);\n }\n };\n }\n\n /**\n * Add a response interceptor\n */\n addResponseInterceptor(interceptor: ResponseInterceptor): () => void {\n this.response.push(interceptor);\n return () => {\n const index = this.response.indexOf(interceptor);\n if (index !== -1) {\n this.response.splice(index, 1);\n }\n };\n }\n\n /**\n * Process a request through the interceptor chain\n * Returns either:\n * - { type: 'continue', request } - continue with (possibly modified) request\n * - { type: 'mock', response } - return mock response immediately\n * - { type: 'error', error } - throw error\n */\n async processRequest(\n request: JsonRpcRequest,\n meta: InterceptorContext['meta'],\n ): Promise<\n | { type: 'continue'; request: JsonRpcRequest }\n | { type: 'mock'; response: JsonRpcResponse }\n | { type: 'error'; error: Error }\n > {\n let currentRequest = request;\n\n // 1. Check mocks first\n const mockDef = this.mocks.match(request);\n if (mockDef) {\n // Apply delay if specified\n if (mockDef.delay && mockDef.delay > 0) {\n await sleep(mockDef.delay);\n }\n\n // Get mock response\n let mockResponse: JsonRpcResponse;\n if (typeof mockDef.response === 'function') {\n mockResponse = await mockDef.response(request);\n } else {\n mockResponse = mockDef.response;\n }\n\n // Ensure the response ID matches the request ID\n return {\n type: 'mock',\n response: { ...mockResponse, id: request.id ?? mockResponse.id },\n };\n }\n\n // 2. Run request interceptors\n for (const interceptor of this.request) {\n const ctx: InterceptorContext = {\n request: currentRequest,\n meta,\n };\n\n const result = await interceptor(ctx);\n\n switch (result.action) {\n case 'passthrough':\n // Continue with current request\n break;\n case 'modify':\n // Use modified request\n currentRequest = result.request;\n break;\n case 'mock':\n // Return mock response immediately\n return {\n type: 'mock',\n response: { ...result.response, id: request.id ?? result.response.id },\n };\n case 'error':\n return { type: 'error', error: result.error };\n }\n }\n\n return { type: 'continue', request: currentRequest };\n }\n\n /**\n * Process a response through the interceptor chain\n */\n async processResponse(\n request: JsonRpcRequest,\n response: JsonRpcResponse,\n durationMs: number,\n ): Promise<JsonRpcResponse> {\n let currentResponse = response;\n\n for (const interceptor of this.response) {\n const ctx: ResponseInterceptorContext = {\n request,\n response: currentResponse,\n durationMs,\n };\n\n const result = await interceptor(ctx);\n\n switch (result.action) {\n case 'passthrough':\n // Continue with current response\n break;\n case 'modify':\n // Use modified response\n currentResponse = result.response;\n break;\n }\n }\n\n return currentResponse;\n }\n\n /**\n * Clear all interceptors and mocks\n */\n clear(): void {\n this.request = [];\n this.response = [];\n this.mocks.clear();\n }\n}\n\n/**\n * Sleep helper\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Convenience interceptor creators\n */\nexport const interceptors = {\n /**\n * Create an interceptor that logs all requests\n */\n logger(logFn: (message: string, data?: unknown) => void = console.log): RequestInterceptor {\n return (ctx) => {\n logFn(`[MCP Request] ${ctx.request.method}`, ctx.request.params);\n return { action: 'passthrough' };\n };\n },\n\n /**\n * Create an interceptor that adds latency to all requests\n */\n delay(ms: number): RequestInterceptor {\n return async () => {\n await sleep(ms);\n return { action: 'passthrough' };\n };\n },\n\n /**\n * Create an interceptor that fails requests matching a condition\n */\n failWhen(condition: (ctx: InterceptorContext) => boolean, error: Error | string): RequestInterceptor {\n return (ctx) => {\n if (condition(ctx)) {\n const err = typeof error === 'string' ? new Error(error) : error;\n return { action: 'error', error: err };\n }\n return { action: 'passthrough' };\n };\n },\n\n /**\n * Create an interceptor that modifies specific methods\n */\n modifyMethod(method: string, modifier: (request: JsonRpcRequest) => JsonRpcRequest): RequestInterceptor {\n return (ctx) => {\n if (ctx.request.method === method) {\n return { action: 'modify', request: modifier(ctx.request) };\n }\n return { action: 'passthrough' };\n };\n },\n\n /**\n * Create a response interceptor that logs responses\n */\n responseLogger(logFn: (message: string, data?: unknown) => void = console.log): ResponseInterceptor {\n return (ctx) => {\n const status = ctx.response.error ? 'ERROR' : 'OK';\n logFn(`[MCP Response] ${ctx.request.method} ${status} (${ctx.durationMs}ms)`, ctx.response);\n return { action: 'passthrough' };\n };\n },\n\n /**\n * Create a response interceptor that modifies specific responses\n */\n modifyResponse(method: string, modifier: (response: JsonRpcResponse) => JsonRpcResponse): ResponseInterceptor {\n return (ctx) => {\n if (ctx.request.method === method) {\n return { action: 'modify', response: modifier(ctx.response) };\n }\n return { action: 'passthrough' };\n };\n },\n};\n"]}
@@ -1,7 +0,0 @@
1
- "use strict";
2
- /**
3
- * @file interceptor.types.ts
4
- * @description Types for request/response interception and mocking
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- //# sourceMappingURL=interceptor.types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"interceptor.types.js","sourceRoot":"","sources":["../../../src/interceptor/interceptor.types.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/**\n * @file interceptor.types.ts\n * @description Types for request/response interception and mocking\n */\n\nimport type { JsonRpcRequest, JsonRpcResponse } from '../transport/transport.interface';\n\n/**\n * Interceptor context passed to handler functions\n */\nexport interface InterceptorContext {\n /** The original request */\n request: JsonRpcRequest;\n /** Request metadata */\n meta: {\n /** Timestamp when request was made */\n timestamp: Date;\n /** Transport type being used */\n transport: string;\n /** Session ID if available */\n sessionId?: string;\n };\n}\n\n/**\n * Result of an interceptor - can modify, mock, or pass through\n */\nexport type InterceptorResult =\n | { action: 'passthrough' }\n | { action: 'modify'; request: JsonRpcRequest }\n | { action: 'mock'; response: JsonRpcResponse }\n | { action: 'error'; error: Error };\n\n/**\n * Function signature for request interceptors\n */\nexport type RequestInterceptor = (ctx: InterceptorContext) => InterceptorResult | Promise<InterceptorResult>;\n\n/**\n * Response interceptor context\n */\nexport interface ResponseInterceptorContext {\n /** The original request */\n request: JsonRpcRequest;\n /** The response from the server */\n response: JsonRpcResponse;\n /** Duration of the request in ms */\n durationMs: number;\n}\n\n/**\n * Response interceptor result\n */\nexport type ResponseInterceptorResult = { action: 'passthrough' } | { action: 'modify'; response: JsonRpcResponse };\n\n/**\n * Function signature for response interceptors\n */\nexport type ResponseInterceptor = (\n ctx: ResponseInterceptorContext,\n) => ResponseInterceptorResult | Promise<ResponseInterceptorResult>;\n\n/**\n * Mock definition for a specific method\n */\nexport interface MockDefinition {\n /** Method name to mock (e.g., 'tools/call', 'resources/read') */\n method: string;\n /** Optional matcher for params - if provided, only matches when params match */\n params?: Record<string, unknown> | ((params: Record<string, unknown>) => boolean);\n /** The mock response to return */\n response: JsonRpcResponse | ((request: JsonRpcRequest) => JsonRpcResponse | Promise<JsonRpcResponse>);\n /** Number of times this mock should be used (default: Infinity) */\n times?: number;\n /** Delay in ms before returning the response (simulates latency) */\n delay?: number;\n}\n\n/**\n * Mock registry for managing active mocks\n */\nexport interface MockRegistry {\n /** Add a mock */\n add(mock: MockDefinition): MockHandle;\n /** Remove all mocks */\n clear(): void;\n /** Get all active mocks */\n getAll(): MockDefinition[];\n /** Check if a request matches any mock */\n match(request: JsonRpcRequest): MockDefinition | undefined;\n}\n\n/**\n * Handle returned when adding a mock - allows removal\n */\nexport interface MockHandle {\n /** Remove this specific mock */\n remove(): void;\n /** Check how many times this mock was called */\n callCount(): number;\n /** Get all calls made to this mock */\n calls(): JsonRpcRequest[];\n}\n\n/**\n * Interceptor chain configuration\n */\nexport interface InterceptorChain {\n /** Request interceptors (run before request) */\n request: RequestInterceptor[];\n /** Response interceptors (run after response) */\n response: ResponseInterceptor[];\n /** Mock registry */\n mocks: MockRegistry;\n\n /**\n * Process a request through the interceptor chain\n */\n processRequest(\n request: JsonRpcRequest,\n meta: InterceptorContext['meta'],\n ): Promise<\n | { type: 'continue'; request: JsonRpcRequest }\n | { type: 'mock'; response: JsonRpcResponse }\n | { type: 'error'; error: Error }\n >;\n\n /**\n * Process a response through the interceptor chain\n */\n processResponse(request: JsonRpcRequest, response: JsonRpcResponse, durationMs: number): Promise<JsonRpcResponse>;\n}\n"]}