@frontmcp/testing 0.6.1 → 0.6.3
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.
- package/esm/fixtures/index.mjs +2377 -0
- package/esm/index.mjs +4768 -0
- package/esm/matchers/index.mjs +646 -0
- package/esm/package.json +122 -0
- package/esm/playwright/index.mjs +19 -0
- package/esm/setup.mjs +680 -0
- package/fixtures/index.js +2418 -0
- package/index.js +4866 -0
- package/jest-preset.js +3 -3
- package/matchers/index.js +673 -0
- package/package.json +51 -23
- package/playwright/index.js +46 -0
- package/setup.js +651 -0
- package/src/assertions/index.js +0 -18
- package/src/assertions/index.js.map +0 -1
- package/src/assertions/mcp-assertions.js +0 -220
- package/src/assertions/mcp-assertions.js.map +0 -1
- package/src/auth/auth-headers.js +0 -62
- package/src/auth/auth-headers.js.map +0 -1
- package/src/auth/index.js +0 -15
- package/src/auth/index.js.map +0 -1
- package/src/auth/mock-api-server.js +0 -200
- package/src/auth/mock-api-server.js.map +0 -1
- package/src/auth/mock-oauth-server.js +0 -253
- package/src/auth/mock-oauth-server.js.map +0 -1
- package/src/auth/token-factory.js +0 -181
- package/src/auth/token-factory.js.map +0 -1
- package/src/auth/user-fixtures.js +0 -92
- package/src/auth/user-fixtures.js.map +0 -1
- package/src/client/index.js +0 -12
- package/src/client/index.js.map +0 -1
- package/src/client/mcp-test-client.builder.js +0 -163
- package/src/client/mcp-test-client.builder.js.map +0 -1
- package/src/client/mcp-test-client.js +0 -937
- package/src/client/mcp-test-client.js.map +0 -1
- package/src/client/mcp-test-client.types.js +0 -16
- package/src/client/mcp-test-client.types.js.map +0 -1
- package/src/errors/index.js +0 -85
- package/src/errors/index.js.map +0 -1
- package/src/example-tools/index.js +0 -40
- package/src/example-tools/index.js.map +0 -1
- package/src/example-tools/tool-configs.js +0 -222
- package/src/example-tools/tool-configs.js.map +0 -1
- package/src/expect.js +0 -31
- package/src/expect.js.map +0 -1
- package/src/fixtures/fixture-types.js +0 -7
- package/src/fixtures/fixture-types.js.map +0 -1
- package/src/fixtures/index.js +0 -16
- package/src/fixtures/index.js.map +0 -1
- package/src/fixtures/test-fixture.js +0 -311
- package/src/fixtures/test-fixture.js.map +0 -1
- package/src/http-mock/http-mock.js +0 -544
- package/src/http-mock/http-mock.js.map +0 -1
- package/src/http-mock/http-mock.types.js +0 -10
- package/src/http-mock/http-mock.types.js.map +0 -1
- package/src/http-mock/index.js +0 -11
- package/src/http-mock/index.js.map +0 -1
- package/src/index.js +0 -167
- package/src/index.js.map +0 -1
- package/src/interceptor/index.js +0 -15
- package/src/interceptor/index.js.map +0 -1
- package/src/interceptor/interceptor-chain.js +0 -207
- package/src/interceptor/interceptor-chain.js.map +0 -1
- package/src/interceptor/interceptor.types.js +0 -7
- package/src/interceptor/interceptor.types.js.map +0 -1
- package/src/interceptor/mock-registry.js +0 -189
- package/src/interceptor/mock-registry.js.map +0 -1
- package/src/matchers/index.js +0 -12
- package/src/matchers/index.js.map +0 -1
- package/src/matchers/matcher-types.js +0 -10
- package/src/matchers/matcher-types.js.map +0 -1
- package/src/matchers/mcp-matchers.js +0 -395
- package/src/matchers/mcp-matchers.js.map +0 -1
- package/src/platform/index.js +0 -47
- package/src/platform/index.js.map +0 -1
- package/src/platform/platform-client-info.js +0 -155
- package/src/platform/platform-client-info.js.map +0 -1
- package/src/platform/platform-types.js +0 -110
- package/src/platform/platform-types.js.map +0 -1
- package/src/playwright/index.js +0 -49
- package/src/playwright/index.js.map +0 -1
- package/src/server/index.js +0 -10
- package/src/server/index.js.map +0 -1
- package/src/server/test-server.js +0 -341
- package/src/server/test-server.js.map +0 -1
- package/src/setup.js +0 -30
- package/src/setup.js.map +0 -1
- package/src/transport/index.js +0 -10
- package/src/transport/index.js.map +0 -1
- package/src/transport/streamable-http.transport.js +0 -438
- package/src/transport/streamable-http.transport.js.map +0 -1
- package/src/transport/transport.interface.js +0 -7
- package/src/transport/transport.interface.js.map +0 -1
- package/src/ui/index.js +0 -23
- package/src/ui/index.js.map +0 -1
- package/src/ui/ui-assertions.js +0 -367
- package/src/ui/ui-assertions.js.map +0 -1
- package/src/ui/ui-matchers.js +0 -493
- package/src/ui/ui-matchers.js.map +0 -1
- /package/{src/assertions → assertions}/index.d.ts +0 -0
- /package/{src/assertions → assertions}/mcp-assertions.d.ts +0 -0
- /package/{src/auth → auth}/auth-headers.d.ts +0 -0
- /package/{src/auth → auth}/index.d.ts +0 -0
- /package/{src/auth → auth}/mock-api-server.d.ts +0 -0
- /package/{src/auth → auth}/mock-oauth-server.d.ts +0 -0
- /package/{src/auth → auth}/token-factory.d.ts +0 -0
- /package/{src/auth → auth}/user-fixtures.d.ts +0 -0
- /package/{src/client → client}/index.d.ts +0 -0
- /package/{src/client → client}/mcp-test-client.builder.d.ts +0 -0
- /package/{src/client → client}/mcp-test-client.d.ts +0 -0
- /package/{src/client → client}/mcp-test-client.types.d.ts +0 -0
- /package/{src/errors → errors}/index.d.ts +0 -0
- /package/{src/example-tools → example-tools}/index.d.ts +0 -0
- /package/{src/example-tools → example-tools}/tool-configs.d.ts +0 -0
- /package/{src/expect.d.ts → expect.d.ts} +0 -0
- /package/{src/fixtures → fixtures}/fixture-types.d.ts +0 -0
- /package/{src/fixtures → fixtures}/index.d.ts +0 -0
- /package/{src/fixtures → fixtures}/test-fixture.d.ts +0 -0
- /package/{src/http-mock → http-mock}/http-mock.d.ts +0 -0
- /package/{src/http-mock → http-mock}/http-mock.types.d.ts +0 -0
- /package/{src/http-mock → http-mock}/index.d.ts +0 -0
- /package/{src/index.d.ts → index.d.ts} +0 -0
- /package/{src/interceptor → interceptor}/index.d.ts +0 -0
- /package/{src/interceptor → interceptor}/interceptor-chain.d.ts +0 -0
- /package/{src/interceptor → interceptor}/interceptor.types.d.ts +0 -0
- /package/{src/interceptor → interceptor}/mock-registry.d.ts +0 -0
- /package/{src/matchers → matchers}/index.d.ts +0 -0
- /package/{src/matchers → matchers}/matcher-types.d.ts +0 -0
- /package/{src/matchers → matchers}/mcp-matchers.d.ts +0 -0
- /package/{src/platform → platform}/index.d.ts +0 -0
- /package/{src/platform → platform}/platform-client-info.d.ts +0 -0
- /package/{src/platform → platform}/platform-types.d.ts +0 -0
- /package/{src/playwright → playwright}/index.d.ts +0 -0
- /package/{src/server → server}/index.d.ts +0 -0
- /package/{src/server → server}/test-server.d.ts +0 -0
- /package/{src/setup.d.ts → setup.d.ts} +0 -0
- /package/{src/transport → transport}/index.d.ts +0 -0
- /package/{src/transport → transport}/streamable-http.transport.d.ts +0 -0
- /package/{src/transport → transport}/transport.interface.d.ts +0 -0
- /package/{src/ui → ui}/index.d.ts +0 -0
- /package/{src/ui → ui}/ui-assertions.d.ts +0 -0
- /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":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;;;;AAEH,sEAAsE;AACtE,SAAS;AACT,sEAAsE;AAEtE,4DAAyD;AAAhD,gHAAA,aAAa,OAAA;AACtB,4EAAwE;AAA/D,+HAAA,oBAAoB,OAAA;AAwB7B,mFAAgF;AAAvE,oIAAA,uBAAuB,OAAA;AAEhC,sEAAsE;AACtE,OAAO;AACP,sEAAsE;AAEtE,sDAAwD;AAA/C,iHAAA,gBAAgB,OAAA;AAEzB,oDAAkD;AAAzC,2GAAA,WAAW,OAAA;AACpB,sDAAiE;AAAxD,0GAAA,SAAS,OAAA;AAAE,+GAAA,cAAc,OAAA;AAElC,8DAA2D;AAAlD,oHAAA,eAAe,OAAA;AAExB,0DAAuD;AAA9C,gHAAA,aAAa,OAAA;AAGtB,sEAAsE;AACtE,SAAS;AACT,sEAAsE;AAEtE,oDAAkD;AAAzC,yGAAA,UAAU,OAAA;AAGnB,sEAAsE;AACtE,aAAa;AACb,sEAAsE;AAEtE,8DAUqC;AATnC,+GAAA,aAAa,OAAA;AACb,8GAAA,YAAY,OAAA;AACZ,kHAAA,gBAAgB,OAAA;AAChB,0HAAA,wBAAwB,OAAA;AACxB,gHAAA,cAAc,OAAA;AACd,8GAAA,YAAY,OAAA;AACZ,yGAAA,OAAO,OAAA;AACP,gHAAA,cAAc,OAAA;AACd,6GAAA,WAAW,OAAA;AAGb,sEAAsE;AACtE,SAAS;AACT,sEAAsE;AAEtE,wCAOwB;AANtB,wGAAA,eAAe,OAAA;AACf,wGAAA,eAAe,OAAA;AACf,qGAAA,YAAY,OAAA;AACZ,yGAAA,gBAAgB,OAAA;AAChB,yGAAA,gBAAgB,OAAA;AAChB,uGAAA,cAAc,OAAA;AAyBhB,sEAAsE;AACtE,yBAAyB;AACzB,sEAAsE;AAEtE,uCAAkC;AAAzB,gGAAA,IAAI,OAAA;AAWb,sEAAsE;AACtE,uBAAuB;AACvB,sEAAsE;AAEtE,4EAA4E;AAC5E,+EAA+E;AAC/E,mCAAkC;AAAzB,gGAAA,MAAM,OAAA;AAEf,sEAAsE;AACtE,kBAAkB;AAClB,sEAAsE;AAEtE,uCAAyC;AAAhC,uGAAA,WAAW,OAAA;AAGpB,sEAAsE;AACtE,yBAAyB;AACzB,sEAAsE;AAEtE,6CAAyG;AAAhG,kHAAA,mBAAmB,OAAA;AAAE,sHAAA,uBAAuB,OAAA;AAAE,2GAAA,YAAY,OAAA;AAAE,2GAAA,YAAY,OAAA;AAejF,sEAAsE;AACtE,qCAAqC;AACrC,sEAAsE;AAEtE,yCAAqD;AAA5C,qGAAA,QAAQ,OAAA;AAAE,yGAAA,YAAY,OAAA;AAa/B,sEAAsE;AACtE,aAAa;AACb,sEAAsE;AAEtE,2BAAgD;AAAvC,gGAAA,UAAU,OAAA;AAAE,kGAAA,YAAY,OAAA;AAQjC,uCAaoB;AAZlB,oHAAA,wBAAwB,OAAA;AACxB,+GAAA,mBAAmB,OAAA;AACnB,4GAAA,gBAAgB,OAAA;AAChB,6GAAA,iBAAiB,OAAA;AACjB,8GAAA,kBAAkB,OAAA;AAClB,oHAAA,wBAAwB,OAAA;AACxB,mHAAA,uBAAuB,OAAA;AACvB,oHAAA,wBAAwB,OAAA;AACxB,iHAAA,qBAAqB,OAAA;AACrB,0GAAA,cAAc,OAAA;AACd,gHAAA,oBAAoB,OAAA;AACpB,uHAAA,2BAA2B,OAAA;AAG7B,sEAAsE;AACtE,2CAA2C;AAC3C,sEAAsE;AAEtE,iDAkByB;AAjBvB,sBAAsB;AACtB,qHAAA,oBAAoB,OAAA;AACpB,oHAAA,mBAAmB,OAAA;AACnB,uHAAA,sBAAsB,OAAA;AACtB,wHAAA,uBAAuB,OAAA;AACvB,sHAAA,qBAAqB,OAAA;AACrB,uHAAA,sBAAsB,OAAA;AACtB,oBAAoB;AACpB,0HAAA,yBAAyB,OAAA;AACzB,yHAAA,wBAAwB,OAAA;AACxB,qBAAqB;AACrB,qIAAA,oCAAoC,OAAA;AACpC,oIAAA,mCAAmC,OAAA;AACnC,sIAAA,qCAAqC,OAAA;AACrC,qIAAA,oCAAoC,OAAA;AACpC,uIAAA,sCAAsC,OAAA;AACtC,sIAAA,qCAAqC,OAAA","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"]}
|
package/src/interceptor/index.js
DELETED
|
@@ -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 +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"]}
|