@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
@@ -1,253 +0,0 @@
1
- "use strict";
2
- /**
3
- * @file mock-oauth-server.ts
4
- * @description Mock OAuth server for testing transparent auth mode
5
- *
6
- * This module provides a mock OAuth/OIDC server that serves:
7
- * - JWKS endpoint for token verification
8
- * - OAuth metadata endpoint (optional)
9
- * - Token endpoint for anonymous tokens (optional)
10
- *
11
- * @example
12
- * ```typescript
13
- * import { MockOAuthServer, TestTokenFactory } from '@frontmcp/testing';
14
- *
15
- * const tokenFactory = new TestTokenFactory();
16
- * const oauthServer = new MockOAuthServer(tokenFactory);
17
- *
18
- * // Start the mock server
19
- * await oauthServer.start();
20
- *
21
- * // Configure your MCP server to use this mock
22
- * // IDP_PROVIDER_URL = oauthServer.baseUrl
23
- *
24
- * // Create tokens using the same factory
25
- * const token = await tokenFactory.createTestToken({ sub: 'user-123' });
26
- *
27
- * // Stop when done
28
- * await oauthServer.stop();
29
- * ```
30
- */
31
- Object.defineProperty(exports, "__esModule", { value: true });
32
- exports.MockOAuthServer = void 0;
33
- const http_1 = require("http");
34
- // ═══════════════════════════════════════════════════════════════════
35
- // MOCK OAUTH SERVER
36
- // ═══════════════════════════════════════════════════════════════════
37
- /**
38
- * Mock OAuth/OIDC server for testing transparent auth mode
39
- *
40
- * Serves JWKS from a TestTokenFactory so that MCP servers can
41
- * validate test tokens without connecting to a real IdP.
42
- */
43
- class MockOAuthServer {
44
- tokenFactory;
45
- options;
46
- server = null;
47
- _info = null;
48
- connections = new Set();
49
- constructor(tokenFactory, options = {}) {
50
- this.tokenFactory = tokenFactory;
51
- this.options = options;
52
- }
53
- /**
54
- * Start the mock OAuth server
55
- */
56
- async start() {
57
- if (this.server) {
58
- throw new Error('Mock OAuth server is already running');
59
- }
60
- const port = this.options.port ?? 0; // 0 = random available port
61
- return new Promise((resolve, reject) => {
62
- const server = (0, http_1.createServer)(this.handleRequest.bind(this));
63
- this.server = server;
64
- // Track connections for proper cleanup
65
- server.on('connection', (socket) => {
66
- this.connections.add(socket);
67
- socket.on('close', () => this.connections.delete(socket));
68
- });
69
- server.on('error', (err) => {
70
- this.log(`Server error: ${err.message}`);
71
- reject(err);
72
- });
73
- server.listen(port, () => {
74
- const address = server.address();
75
- if (!address || typeof address === 'string') {
76
- reject(new Error('Failed to get server address'));
77
- return;
78
- }
79
- const actualPort = address.port;
80
- const issuer = this.options.issuer ?? `http://localhost:${actualPort}`;
81
- this._info = {
82
- baseUrl: `http://localhost:${actualPort}`,
83
- port: actualPort,
84
- issuer,
85
- jwksUrl: `http://localhost:${actualPort}/.well-known/jwks.json`,
86
- };
87
- this.log(`Mock OAuth server started at ${this._info.baseUrl}`);
88
- resolve(this._info);
89
- });
90
- });
91
- }
92
- /**
93
- * Stop the mock OAuth server
94
- */
95
- async stop() {
96
- const server = this.server;
97
- if (!server) {
98
- return;
99
- }
100
- // Destroy all active connections to allow server.close() to complete
101
- for (const socket of this.connections) {
102
- socket.destroy();
103
- }
104
- this.connections.clear();
105
- return new Promise((resolve, reject) => {
106
- server.close((err) => {
107
- if (err) {
108
- reject(err);
109
- }
110
- else {
111
- this.server = null;
112
- this._info = null;
113
- this.log('Mock OAuth server stopped');
114
- resolve();
115
- }
116
- });
117
- });
118
- }
119
- /**
120
- * Get server info
121
- */
122
- get info() {
123
- if (!this._info) {
124
- throw new Error('Mock OAuth server is not running');
125
- }
126
- return this._info;
127
- }
128
- /**
129
- * Get the token factory (for creating tokens)
130
- */
131
- getTokenFactory() {
132
- return this.tokenFactory;
133
- }
134
- // ═══════════════════════════════════════════════════════════════════
135
- // PRIVATE
136
- // ═══════════════════════════════════════════════════════════════════
137
- async handleRequest(req, res) {
138
- const url = req.url ?? '/';
139
- this.log(`${req.method} ${url}`);
140
- // CORS headers
141
- res.setHeader('Access-Control-Allow-Origin', '*');
142
- res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
143
- res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
144
- if (req.method === 'OPTIONS') {
145
- res.writeHead(204);
146
- res.end();
147
- return;
148
- }
149
- try {
150
- if (url === '/.well-known/jwks.json' || url === '/.well-known/jwks') {
151
- await this.handleJwks(req, res);
152
- }
153
- else if (url === '/.well-known/openid-configuration') {
154
- await this.handleOidcConfig(req, res);
155
- }
156
- else if (url === '/.well-known/oauth-authorization-server') {
157
- await this.handleOAuthMetadata(req, res);
158
- }
159
- else if (url === '/oauth/token') {
160
- await this.handleTokenEndpoint(req, res);
161
- }
162
- else {
163
- res.writeHead(404, { 'Content-Type': 'application/json' });
164
- res.end(JSON.stringify({ error: 'not_found', error_description: 'Endpoint not found' }));
165
- }
166
- }
167
- catch (error) {
168
- this.log(`Error handling request: ${error}`);
169
- res.writeHead(500, { 'Content-Type': 'application/json' });
170
- res.end(JSON.stringify({ error: 'server_error', error_description: 'Internal server error' }));
171
- }
172
- }
173
- async handleJwks(_req, res) {
174
- const jwks = await this.tokenFactory.getPublicJwks();
175
- res.writeHead(200, { 'Content-Type': 'application/json' });
176
- res.end(JSON.stringify(jwks));
177
- this.log('Served JWKS');
178
- }
179
- async handleOidcConfig(_req, res) {
180
- const issuer = this._info?.issuer ?? 'http://localhost';
181
- const config = {
182
- issuer,
183
- authorization_endpoint: `${issuer}/oauth/authorize`,
184
- token_endpoint: `${issuer}/oauth/token`,
185
- jwks_uri: `${issuer}/.well-known/jwks.json`,
186
- response_types_supported: ['code', 'token'],
187
- subject_types_supported: ['public'],
188
- id_token_signing_alg_values_supported: ['RS256'],
189
- scopes_supported: ['openid', 'profile', 'email'],
190
- token_endpoint_auth_methods_supported: ['client_secret_basic', 'client_secret_post', 'none'],
191
- claims_supported: ['sub', 'iss', 'aud', 'exp', 'iat', 'email', 'name'],
192
- grant_types_supported: ['authorization_code', 'refresh_token', 'client_credentials', 'anonymous'],
193
- };
194
- res.writeHead(200, { 'Content-Type': 'application/json' });
195
- res.end(JSON.stringify(config));
196
- this.log('Served OIDC configuration');
197
- }
198
- async handleOAuthMetadata(_req, res) {
199
- const issuer = this._info?.issuer ?? 'http://localhost';
200
- const metadata = {
201
- issuer,
202
- authorization_endpoint: `${issuer}/oauth/authorize`,
203
- token_endpoint: `${issuer}/oauth/token`,
204
- jwks_uri: `${issuer}/.well-known/jwks.json`,
205
- response_types_supported: ['code', 'token'],
206
- grant_types_supported: ['authorization_code', 'refresh_token', 'client_credentials', 'anonymous'],
207
- token_endpoint_auth_methods_supported: ['client_secret_basic', 'client_secret_post', 'none'],
208
- scopes_supported: ['openid', 'profile', 'email', 'anonymous'],
209
- };
210
- res.writeHead(200, { 'Content-Type': 'application/json' });
211
- res.end(JSON.stringify(metadata));
212
- this.log('Served OAuth metadata');
213
- }
214
- async handleTokenEndpoint(req, res) {
215
- // Parse request body
216
- const body = await this.readBody(req);
217
- const params = new URLSearchParams(body);
218
- const grantType = params.get('grant_type');
219
- if (grantType === 'anonymous') {
220
- // Issue an anonymous token
221
- const token = await this.tokenFactory.createAnonymousToken();
222
- res.writeHead(200, { 'Content-Type': 'application/json' });
223
- res.end(JSON.stringify({
224
- access_token: token,
225
- token_type: 'Bearer',
226
- expires_in: 3600,
227
- }));
228
- this.log('Issued anonymous token');
229
- }
230
- else {
231
- res.writeHead(400, { 'Content-Type': 'application/json' });
232
- res.end(JSON.stringify({
233
- error: 'unsupported_grant_type',
234
- error_description: 'Only anonymous grant type is supported in mock server',
235
- }));
236
- }
237
- }
238
- readBody(req) {
239
- return new Promise((resolve, reject) => {
240
- const chunks = [];
241
- req.on('data', (chunk) => chunks.push(chunk));
242
- req.on('end', () => resolve(Buffer.concat(chunks).toString()));
243
- req.on('error', reject);
244
- });
245
- }
246
- log(message) {
247
- if (this.options.debug) {
248
- console.log(`[MockOAuthServer] ${message}`);
249
- }
250
- }
251
- }
252
- exports.MockOAuthServer = MockOAuthServer;
253
- //# sourceMappingURL=mock-oauth-server.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mock-oauth-server.js","sourceRoot":"","sources":["../../../src/auth/mock-oauth-server.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @file mock-oauth-server.ts\n * @description Mock OAuth server for testing transparent auth mode\n *\n * This module provides a mock OAuth/OIDC server that serves:\n * - JWKS endpoint for token verification\n * - OAuth metadata endpoint (optional)\n * - Token endpoint for anonymous tokens (optional)\n *\n * @example\n * ```typescript\n * import { MockOAuthServer, TestTokenFactory } from '@frontmcp/testing';\n *\n * const tokenFactory = new TestTokenFactory();\n * const oauthServer = new MockOAuthServer(tokenFactory);\n *\n * // Start the mock server\n * await oauthServer.start();\n *\n * // Configure your MCP server to use this mock\n * // IDP_PROVIDER_URL = oauthServer.baseUrl\n *\n * // Create tokens using the same factory\n * const token = await tokenFactory.createTestToken({ sub: 'user-123' });\n *\n * // Stop when done\n * await oauthServer.stop();\n * ```\n */\n\nimport { createServer, Server, IncomingMessage, ServerResponse } from 'http';\nimport type { TestTokenFactory } from './token-factory';\n\n// ═══════════════════════════════════════════════════════════════════\n// TYPES\n// ═══════════════════════════════════════════════════════════════════\n\nexport interface MockOAuthServerOptions {\n /** Port to listen on (default: random available port) */\n port?: number;\n /** Issuer URL (default: http://localhost:{port}) */\n issuer?: string;\n /** Enable debug logging */\n debug?: boolean;\n}\n\nexport interface MockOAuthServerInfo {\n /** Base URL of the server */\n baseUrl: string;\n /** Port the server is listening on */\n port: number;\n /** Issuer URL */\n issuer: string;\n /** JWKS endpoint URL */\n jwksUrl: string;\n}\n\n// ═══════════════════════════════════════════════════════════════════\n// MOCK OAUTH SERVER\n// ═══════════════════════════════════════════════════════════════════\n\n/**\n * Mock OAuth/OIDC server for testing transparent auth mode\n *\n * Serves JWKS from a TestTokenFactory so that MCP servers can\n * validate test tokens without connecting to a real IdP.\n */\nexport class MockOAuthServer {\n private readonly tokenFactory: TestTokenFactory;\n private readonly options: MockOAuthServerOptions;\n private server: Server | null = null;\n private _info: MockOAuthServerInfo | null = null;\n private connections: Set<import('net').Socket> = new Set();\n\n constructor(tokenFactory: TestTokenFactory, options: MockOAuthServerOptions = {}) {\n this.tokenFactory = tokenFactory;\n this.options = options;\n }\n\n /**\n * Start the mock OAuth server\n */\n async start(): Promise<MockOAuthServerInfo> {\n if (this.server) {\n throw new Error('Mock OAuth server is already running');\n }\n\n const port = this.options.port ?? 0; // 0 = random available port\n\n return new Promise((resolve, reject) => {\n const server = createServer(this.handleRequest.bind(this));\n this.server = server;\n\n // Track connections for proper cleanup\n server.on('connection', (socket) => {\n this.connections.add(socket);\n socket.on('close', () => this.connections.delete(socket));\n });\n\n server.on('error', (err) => {\n this.log(`Server error: ${err.message}`);\n reject(err);\n });\n\n server.listen(port, () => {\n const address = server.address();\n if (!address || typeof address === 'string') {\n reject(new Error('Failed to get server address'));\n return;\n }\n\n const actualPort = address.port;\n const issuer = this.options.issuer ?? `http://localhost:${actualPort}`;\n\n this._info = {\n baseUrl: `http://localhost:${actualPort}`,\n port: actualPort,\n issuer,\n jwksUrl: `http://localhost:${actualPort}/.well-known/jwks.json`,\n };\n\n this.log(`Mock OAuth server started at ${this._info.baseUrl}`);\n resolve(this._info);\n });\n });\n }\n\n /**\n * Stop the mock OAuth server\n */\n async stop(): Promise<void> {\n const server = this.server;\n if (!server) {\n return;\n }\n\n // Destroy all active connections to allow server.close() to complete\n for (const socket of this.connections) {\n socket.destroy();\n }\n this.connections.clear();\n\n return new Promise((resolve, reject) => {\n server.close((err) => {\n if (err) {\n reject(err);\n } else {\n this.server = null;\n this._info = null;\n this.log('Mock OAuth server stopped');\n resolve();\n }\n });\n });\n }\n\n /**\n * Get server info\n */\n get info(): MockOAuthServerInfo {\n if (!this._info) {\n throw new Error('Mock OAuth server is not running');\n }\n return this._info;\n }\n\n /**\n * Get the token factory (for creating tokens)\n */\n getTokenFactory(): TestTokenFactory {\n return this.tokenFactory;\n }\n\n // ═══════════════════════════════════════════════════════════════════\n // PRIVATE\n // ═══════════════════════════════════════════════════════════════════\n\n private async handleRequest(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const url = req.url ?? '/';\n this.log(`${req.method} ${url}`);\n\n // CORS headers\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n\n try {\n if (url === '/.well-known/jwks.json' || url === '/.well-known/jwks') {\n await this.handleJwks(req, res);\n } else if (url === '/.well-known/openid-configuration') {\n await this.handleOidcConfig(req, res);\n } else if (url === '/.well-known/oauth-authorization-server') {\n await this.handleOAuthMetadata(req, res);\n } else if (url === '/oauth/token') {\n await this.handleTokenEndpoint(req, res);\n } else {\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'not_found', error_description: 'Endpoint not found' }));\n }\n } catch (error) {\n this.log(`Error handling request: ${error}`);\n res.writeHead(500, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'server_error', error_description: 'Internal server error' }));\n }\n }\n\n private async handleJwks(_req: IncomingMessage, res: ServerResponse): Promise<void> {\n const jwks = await this.tokenFactory.getPublicJwks();\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(jwks));\n this.log('Served JWKS');\n }\n\n private async handleOidcConfig(_req: IncomingMessage, res: ServerResponse): Promise<void> {\n const issuer = this._info?.issuer ?? 'http://localhost';\n const config = {\n issuer,\n authorization_endpoint: `${issuer}/oauth/authorize`,\n token_endpoint: `${issuer}/oauth/token`,\n jwks_uri: `${issuer}/.well-known/jwks.json`,\n response_types_supported: ['code', 'token'],\n subject_types_supported: ['public'],\n id_token_signing_alg_values_supported: ['RS256'],\n scopes_supported: ['openid', 'profile', 'email'],\n token_endpoint_auth_methods_supported: ['client_secret_basic', 'client_secret_post', 'none'],\n claims_supported: ['sub', 'iss', 'aud', 'exp', 'iat', 'email', 'name'],\n grant_types_supported: ['authorization_code', 'refresh_token', 'client_credentials', 'anonymous'],\n };\n\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(config));\n this.log('Served OIDC configuration');\n }\n\n private async handleOAuthMetadata(_req: IncomingMessage, res: ServerResponse): Promise<void> {\n const issuer = this._info?.issuer ?? 'http://localhost';\n const metadata = {\n issuer,\n authorization_endpoint: `${issuer}/oauth/authorize`,\n token_endpoint: `${issuer}/oauth/token`,\n jwks_uri: `${issuer}/.well-known/jwks.json`,\n response_types_supported: ['code', 'token'],\n grant_types_supported: ['authorization_code', 'refresh_token', 'client_credentials', 'anonymous'],\n token_endpoint_auth_methods_supported: ['client_secret_basic', 'client_secret_post', 'none'],\n scopes_supported: ['openid', 'profile', 'email', 'anonymous'],\n };\n\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(metadata));\n this.log('Served OAuth metadata');\n }\n\n private async handleTokenEndpoint(req: IncomingMessage, res: ServerResponse): Promise<void> {\n // Parse request body\n const body = await this.readBody(req);\n const params = new URLSearchParams(body);\n const grantType = params.get('grant_type');\n\n if (grantType === 'anonymous') {\n // Issue an anonymous token\n const token = await this.tokenFactory.createAnonymousToken();\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(\n JSON.stringify({\n access_token: token,\n token_type: 'Bearer',\n expires_in: 3600,\n }),\n );\n this.log('Issued anonymous token');\n } else {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(\n JSON.stringify({\n error: 'unsupported_grant_type',\n error_description: 'Only anonymous grant type is supported in mock server',\n }),\n );\n }\n }\n\n private readBody(req: IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n req.on('data', (chunk) => chunks.push(chunk));\n req.on('end', () => resolve(Buffer.concat(chunks).toString()));\n req.on('error', reject);\n });\n }\n\n private log(message: string): void {\n if (this.options.debug) {\n console.log(`[MockOAuthServer] ${message}`);\n }\n }\n}\n"]}
@@ -1,181 +0,0 @@
1
- "use strict";
2
- /**
3
- * @file token-factory.ts
4
- * @description JWT token factory for testing authentication
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.TestTokenFactory = void 0;
8
- const jose_1 = require("jose");
9
- // ═══════════════════════════════════════════════════════════════════
10
- // TOKEN FACTORY CLASS
11
- // ═══════════════════════════════════════════════════════════════════
12
- /**
13
- * Factory for creating JWT tokens for testing
14
- *
15
- * @example
16
- * ```typescript
17
- * const factory = new TestTokenFactory();
18
- *
19
- * // Create a token with claims
20
- * const token = await factory.createTestToken({
21
- * sub: 'user-123',
22
- * scopes: ['read', 'write'],
23
- * });
24
- *
25
- * // Create convenience tokens
26
- * const adminToken = await factory.createAdminToken();
27
- * const userToken = await factory.createUserToken();
28
- * ```
29
- */
30
- class TestTokenFactory {
31
- issuer;
32
- audience;
33
- privateKey = null;
34
- publicKey = null;
35
- jwk = null;
36
- keyId;
37
- constructor(options = {}) {
38
- this.issuer = options.issuer ?? 'https://test.frontmcp.local';
39
- this.audience = options.audience ?? 'frontmcp-test';
40
- this.keyId = `test-key-${Date.now()}`;
41
- }
42
- /**
43
- * Initialize the key pair (called automatically on first use)
44
- */
45
- async ensureKeys() {
46
- if (this.privateKey && this.publicKey)
47
- return;
48
- // Generate RSA key pair
49
- const { publicKey, privateKey } = await (0, jose_1.generateKeyPair)('RS256', {
50
- extractable: true,
51
- });
52
- this.privateKey = privateKey;
53
- this.publicKey = publicKey;
54
- // Export public key as JWK
55
- this.jwk = await (0, jose_1.exportJWK)(publicKey);
56
- this.jwk.kid = this.keyId;
57
- this.jwk.use = 'sig';
58
- this.jwk.alg = 'RS256';
59
- }
60
- /**
61
- * Create a JWT token with the specified claims
62
- */
63
- async createTestToken(options) {
64
- await this.ensureKeys();
65
- const now = Math.floor(Date.now() / 1000);
66
- const exp = options.exp ?? 3600;
67
- const payload = {
68
- iss: options.iss ?? this.issuer,
69
- sub: options.sub,
70
- aud: options.aud ?? this.audience,
71
- iat: now,
72
- exp: now + exp,
73
- scope: options.scopes?.join(' '),
74
- ...options.claims,
75
- };
76
- const token = await new jose_1.SignJWT(payload)
77
- .setProtectedHeader({ alg: 'RS256', kid: this.keyId })
78
- .sign(this.privateKey);
79
- return token;
80
- }
81
- /**
82
- * Create an admin token with full access
83
- */
84
- async createAdminToken(sub = 'admin-001') {
85
- return this.createTestToken({
86
- sub,
87
- scopes: ['admin:*', 'read', 'write', 'delete'],
88
- claims: {
89
- email: 'admin@test.local',
90
- name: 'Test Admin',
91
- role: 'admin',
92
- },
93
- });
94
- }
95
- /**
96
- * Create a regular user token
97
- */
98
- async createUserToken(sub = 'user-001', scopes = ['read', 'write']) {
99
- return this.createTestToken({
100
- sub,
101
- scopes,
102
- claims: {
103
- email: 'user@test.local',
104
- name: 'Test User',
105
- role: 'user',
106
- },
107
- });
108
- }
109
- /**
110
- * Create an anonymous user token
111
- */
112
- async createAnonymousToken() {
113
- return this.createTestToken({
114
- sub: `anon:${Date.now()}`,
115
- scopes: ['anonymous'],
116
- claims: {
117
- name: 'Anonymous',
118
- role: 'anonymous',
119
- },
120
- });
121
- }
122
- /**
123
- * Create an expired token (for testing token expiration)
124
- */
125
- async createExpiredToken(options) {
126
- await this.ensureKeys();
127
- const now = Math.floor(Date.now() / 1000);
128
- const payload = {
129
- iss: this.issuer,
130
- sub: options.sub,
131
- aud: this.audience,
132
- iat: now - 7200, // 2 hours ago
133
- exp: now - 3600, // Expired 1 hour ago
134
- };
135
- const token = await new jose_1.SignJWT(payload)
136
- .setProtectedHeader({ alg: 'RS256', kid: this.keyId })
137
- .sign(this.privateKey);
138
- return token;
139
- }
140
- /**
141
- * Create a token with an invalid signature (for testing signature validation)
142
- */
143
- createTokenWithInvalidSignature(options) {
144
- const now = Math.floor(Date.now() / 1000);
145
- // Create a fake JWT with an invalid signature
146
- const header = Buffer.from(JSON.stringify({ alg: 'RS256', kid: this.keyId })).toString('base64url');
147
- const payload = Buffer.from(JSON.stringify({
148
- iss: this.issuer,
149
- sub: options.sub,
150
- aud: this.audience,
151
- iat: now,
152
- exp: now + 3600,
153
- })).toString('base64url');
154
- // Invalid signature (just random bytes)
155
- const signature = Buffer.from('invalid-signature-' + Date.now()).toString('base64url');
156
- return `${header}.${payload}.${signature}`;
157
- }
158
- /**
159
- * Get the public JWKS for verifying tokens
160
- */
161
- async getPublicJwks() {
162
- await this.ensureKeys();
163
- return {
164
- keys: [this.jwk],
165
- };
166
- }
167
- /**
168
- * Get the issuer URL
169
- */
170
- getIssuer() {
171
- return this.issuer;
172
- }
173
- /**
174
- * Get the audience
175
- */
176
- getAudience() {
177
- return this.audience;
178
- }
179
- }
180
- exports.TestTokenFactory = TestTokenFactory;
181
- //# sourceMappingURL=token-factory.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"token-factory.js","sourceRoot":"","sources":["../../../src/auth/token-factory.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @file token-factory.ts\n * @description JWT token factory for testing authentication\n */\n\nimport { SignJWT, generateKeyPair, exportJWK, type JWTPayload, type JWK } from 'jose';\n\n// ═══════════════════════════════════════════════════════════════════\n// TYPES\n// ═══════════════════════════════════════════════════════════════════\n\nexport interface CreateTokenOptions {\n /** Subject (user ID) - required */\n sub: string;\n /** Issuer URL */\n iss?: string;\n /** Audience */\n aud?: string | string[];\n /** OAuth scopes */\n scopes?: string[];\n /** Expiration time in seconds from now (default: 3600) */\n exp?: number;\n /** Additional custom claims */\n claims?: Record<string, unknown>;\n}\n\nexport interface TokenFactoryOptions {\n /** Default issuer URL */\n issuer?: string;\n /** Default audience */\n audience?: string;\n}\n\n// Type for crypto key\ntype CryptoKeyLike = CryptoKey | Uint8Array;\n\n// ═══════════════════════════════════════════════════════════════════\n// TOKEN FACTORY CLASS\n// ═══════════════════════════════════════════════════════════════════\n\n/**\n * Factory for creating JWT tokens for testing\n *\n * @example\n * ```typescript\n * const factory = new TestTokenFactory();\n *\n * // Create a token with claims\n * const token = await factory.createTestToken({\n * sub: 'user-123',\n * scopes: ['read', 'write'],\n * });\n *\n * // Create convenience tokens\n * const adminToken = await factory.createAdminToken();\n * const userToken = await factory.createUserToken();\n * ```\n */\nexport class TestTokenFactory {\n private readonly issuer: string;\n private readonly audience: string;\n private privateKey: CryptoKeyLike | null = null;\n private publicKey: CryptoKeyLike | null = null;\n private jwk: JWK | null = null;\n private keyId: string;\n\n constructor(options: TokenFactoryOptions = {}) {\n this.issuer = options.issuer ?? 'https://test.frontmcp.local';\n this.audience = options.audience ?? 'frontmcp-test';\n this.keyId = `test-key-${Date.now()}`;\n }\n\n /**\n * Initialize the key pair (called automatically on first use)\n */\n private async ensureKeys(): Promise<void> {\n if (this.privateKey && this.publicKey) return;\n\n // Generate RSA key pair\n const { publicKey, privateKey } = await generateKeyPair('RS256', {\n extractable: true,\n });\n\n this.privateKey = privateKey;\n this.publicKey = publicKey;\n\n // Export public key as JWK\n this.jwk = await exportJWK(publicKey);\n this.jwk.kid = this.keyId;\n this.jwk.use = 'sig';\n this.jwk.alg = 'RS256';\n }\n\n /**\n * Create a JWT token with the specified claims\n */\n async createTestToken(options: CreateTokenOptions): Promise<string> {\n await this.ensureKeys();\n\n const now = Math.floor(Date.now() / 1000);\n const exp = options.exp ?? 3600;\n\n const payload: JWTPayload = {\n iss: options.iss ?? this.issuer,\n sub: options.sub,\n aud: options.aud ?? this.audience,\n iat: now,\n exp: now + exp,\n scope: options.scopes?.join(' '),\n ...options.claims,\n };\n\n const token = await new SignJWT(payload)\n .setProtectedHeader({ alg: 'RS256', kid: this.keyId })\n .sign(this.privateKey!);\n\n return token;\n }\n\n /**\n * Create an admin token with full access\n */\n async createAdminToken(sub = 'admin-001'): Promise<string> {\n return this.createTestToken({\n sub,\n scopes: ['admin:*', 'read', 'write', 'delete'],\n claims: {\n email: 'admin@test.local',\n name: 'Test Admin',\n role: 'admin',\n },\n });\n }\n\n /**\n * Create a regular user token\n */\n async createUserToken(sub = 'user-001', scopes = ['read', 'write']): Promise<string> {\n return this.createTestToken({\n sub,\n scopes,\n claims: {\n email: 'user@test.local',\n name: 'Test User',\n role: 'user',\n },\n });\n }\n\n /**\n * Create an anonymous user token\n */\n async createAnonymousToken(): Promise<string> {\n return this.createTestToken({\n sub: `anon:${Date.now()}`,\n scopes: ['anonymous'],\n claims: {\n name: 'Anonymous',\n role: 'anonymous',\n },\n });\n }\n\n /**\n * Create an expired token (for testing token expiration)\n */\n async createExpiredToken(options: Pick<CreateTokenOptions, 'sub'>): Promise<string> {\n await this.ensureKeys();\n\n const now = Math.floor(Date.now() / 1000);\n\n const payload: JWTPayload = {\n iss: this.issuer,\n sub: options.sub,\n aud: this.audience,\n iat: now - 7200, // 2 hours ago\n exp: now - 3600, // Expired 1 hour ago\n };\n\n const token = await new SignJWT(payload)\n .setProtectedHeader({ alg: 'RS256', kid: this.keyId })\n .sign(this.privateKey!);\n\n return token;\n }\n\n /**\n * Create a token with an invalid signature (for testing signature validation)\n */\n createTokenWithInvalidSignature(options: Pick<CreateTokenOptions, 'sub'>): string {\n const now = Math.floor(Date.now() / 1000);\n\n // Create a fake JWT with an invalid signature\n const header = Buffer.from(JSON.stringify({ alg: 'RS256', kid: this.keyId })).toString('base64url');\n const payload = Buffer.from(\n JSON.stringify({\n iss: this.issuer,\n sub: options.sub,\n aud: this.audience,\n iat: now,\n exp: now + 3600,\n }),\n ).toString('base64url');\n\n // Invalid signature (just random bytes)\n const signature = Buffer.from('invalid-signature-' + Date.now()).toString('base64url');\n\n return `${header}.${payload}.${signature}`;\n }\n\n /**\n * Get the public JWKS for verifying tokens\n */\n async getPublicJwks(): Promise<{ keys: JWK[] }> {\n await this.ensureKeys();\n return {\n keys: [this.jwk!],\n };\n }\n\n /**\n * Get the issuer URL\n */\n getIssuer(): string {\n return this.issuer;\n }\n\n /**\n * Get the audience\n */\n getAudience(): string {\n return this.audience;\n }\n}\n"]}
@@ -1,92 +0,0 @@
1
- "use strict";
2
- /**
3
- * @file user-fixtures.ts
4
- * @description Pre-defined test user fixtures
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.TestUsers = void 0;
8
- exports.createTestUser = createTestUser;
9
- /**
10
- * Pre-defined test users for common testing scenarios
11
- */
12
- exports.TestUsers = {
13
- /**
14
- * Admin user with full access
15
- */
16
- admin: {
17
- sub: 'admin-001',
18
- email: 'admin@test.local',
19
- name: 'Test Admin',
20
- scopes: ['admin:*', 'read', 'write', 'delete'],
21
- role: 'admin',
22
- },
23
- /**
24
- * Regular user with read/write access
25
- */
26
- user: {
27
- sub: 'user-001',
28
- email: 'user@test.local',
29
- name: 'Test User',
30
- scopes: ['read', 'write'],
31
- role: 'user',
32
- },
33
- /**
34
- * Read-only user
35
- */
36
- readOnly: {
37
- sub: 'readonly-001',
38
- email: 'readonly@test.local',
39
- name: 'Read Only User',
40
- scopes: ['read'],
41
- role: 'readonly',
42
- },
43
- /**
44
- * Anonymous user
45
- */
46
- anonymous: {
47
- sub: 'anon:001',
48
- name: 'Anonymous',
49
- scopes: ['anonymous'],
50
- role: 'anonymous',
51
- },
52
- /**
53
- * User with no scopes (for testing access denied)
54
- */
55
- noScopes: {
56
- sub: 'noscopes-001',
57
- email: 'noscopes@test.local',
58
- name: 'No Scopes User',
59
- scopes: [],
60
- role: 'user',
61
- },
62
- /**
63
- * User with only tool execution scope
64
- */
65
- toolsOnly: {
66
- sub: 'toolsonly-001',
67
- email: 'toolsonly@test.local',
68
- name: 'Tools Only User',
69
- scopes: ['tools:execute'],
70
- role: 'user',
71
- },
72
- /**
73
- * User with only resource read scope
74
- */
75
- resourcesOnly: {
76
- sub: 'resourcesonly-001',
77
- email: 'resourcesonly@test.local',
78
- name: 'Resources Only User',
79
- scopes: ['resources:read'],
80
- role: 'user',
81
- },
82
- };
83
- /**
84
- * Create a custom test user
85
- */
86
- function createTestUser(overrides) {
87
- return {
88
- scopes: [],
89
- ...overrides,
90
- };
91
- }
92
- //# sourceMappingURL=user-fixtures.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"user-fixtures.js","sourceRoot":"","sources":["../../../src/auth/user-fixtures.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAmGH,wCAKC;AAzFD;;GAEG;AACU,QAAA,SAAS,GAAoC;IACxD;;OAEG;IACH,KAAK,EAAE;QACL,GAAG,EAAE,WAAW;QAChB,KAAK,EAAE,kBAAkB;QACzB,IAAI,EAAE,YAAY;QAClB,MAAM,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC;QAC9C,IAAI,EAAE,OAAO;KACd;IAED;;OAEG;IACH,IAAI,EAAE;QACJ,GAAG,EAAE,UAAU;QACf,KAAK,EAAE,iBAAiB;QACxB,IAAI,EAAE,WAAW;QACjB,MAAM,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;QACzB,IAAI,EAAE,MAAM;KACb;IAED;;OAEG;IACH,QAAQ,EAAE;QACR,GAAG,EAAE,cAAc;QACnB,KAAK,EAAE,qBAAqB;QAC5B,IAAI,EAAE,gBAAgB;QACtB,MAAM,EAAE,CAAC,MAAM,CAAC;QAChB,IAAI,EAAE,UAAU;KACjB;IAED;;OAEG;IACH,SAAS,EAAE;QACT,GAAG,EAAE,UAAU;QACf,IAAI,EAAE,WAAW;QACjB,MAAM,EAAE,CAAC,WAAW,CAAC;QACrB,IAAI,EAAE,WAAW;KAClB;IAED;;OAEG;IACH,QAAQ,EAAE;QACR,GAAG,EAAE,cAAc;QACnB,KAAK,EAAE,qBAAqB;QAC5B,IAAI,EAAE,gBAAgB;QACtB,MAAM,EAAE,EAAE;QACV,IAAI,EAAE,MAAM;KACb;IAED;;OAEG;IACH,SAAS,EAAE;QACT,GAAG,EAAE,eAAe;QACpB,KAAK,EAAE,sBAAsB;QAC7B,IAAI,EAAE,iBAAiB;QACvB,MAAM,EAAE,CAAC,eAAe,CAAC;QACzB,IAAI,EAAE,MAAM;KACb;IAED;;OAEG;IACH,aAAa,EAAE;QACb,GAAG,EAAE,mBAAmB;QACxB,KAAK,EAAE,0BAA0B;QACjC,IAAI,EAAE,qBAAqB;QAC3B,MAAM,EAAE,CAAC,gBAAgB,CAAC;QAC1B,IAAI,EAAE,MAAM;KACb;CACF,CAAC;AAEF;;GAEG;AACH,SAAgB,cAAc,CAAC,SAAqD;IAClF,OAAO;QACL,MAAM,EAAE,EAAE;QACV,GAAG,SAAS;KACb,CAAC;AACJ,CAAC","sourcesContent":["/**\n * @file user-fixtures.ts\n * @description Pre-defined test user fixtures\n */\n\nexport interface TestUserFixture {\n /** User subject ID */\n sub: string;\n /** User email */\n email?: string;\n /** User display name */\n name?: string;\n /** OAuth scopes */\n scopes: string[];\n /** User role */\n role?: string;\n}\n\n/**\n * Pre-defined test users for common testing scenarios\n */\nexport const TestUsers: Record<string, TestUserFixture> = {\n /**\n * Admin user with full access\n */\n admin: {\n sub: 'admin-001',\n email: 'admin@test.local',\n name: 'Test Admin',\n scopes: ['admin:*', 'read', 'write', 'delete'],\n role: 'admin',\n },\n\n /**\n * Regular user with read/write access\n */\n user: {\n sub: 'user-001',\n email: 'user@test.local',\n name: 'Test User',\n scopes: ['read', 'write'],\n role: 'user',\n },\n\n /**\n * Read-only user\n */\n readOnly: {\n sub: 'readonly-001',\n email: 'readonly@test.local',\n name: 'Read Only User',\n scopes: ['read'],\n role: 'readonly',\n },\n\n /**\n * Anonymous user\n */\n anonymous: {\n sub: 'anon:001',\n name: 'Anonymous',\n scopes: ['anonymous'],\n role: 'anonymous',\n },\n\n /**\n * User with no scopes (for testing access denied)\n */\n noScopes: {\n sub: 'noscopes-001',\n email: 'noscopes@test.local',\n name: 'No Scopes User',\n scopes: [],\n role: 'user',\n },\n\n /**\n * User with only tool execution scope\n */\n toolsOnly: {\n sub: 'toolsonly-001',\n email: 'toolsonly@test.local',\n name: 'Tools Only User',\n scopes: ['tools:execute'],\n role: 'user',\n },\n\n /**\n * User with only resource read scope\n */\n resourcesOnly: {\n sub: 'resourcesonly-001',\n email: 'resourcesonly@test.local',\n name: 'Resources Only User',\n scopes: ['resources:read'],\n role: 'user',\n },\n};\n\n/**\n * Create a custom test user\n */\nexport function createTestUser(overrides: Partial<TestUserFixture> & { sub: string }): TestUserFixture {\n return {\n scopes: [],\n ...overrides,\n };\n}\n"]}
@@ -1,12 +0,0 @@
1
- "use strict";
2
- /**
3
- * @file client/index.ts
4
- * @description MCP Test Client exports
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.McpTestClientBuilder = exports.McpTestClient = void 0;
8
- var mcp_test_client_1 = require("./mcp-test-client");
9
- Object.defineProperty(exports, "McpTestClient", { enumerable: true, get: function () { return mcp_test_client_1.McpTestClient; } });
10
- var mcp_test_client_builder_1 = require("./mcp-test-client.builder");
11
- Object.defineProperty(exports, "McpTestClientBuilder", { enumerable: true, get: function () { return mcp_test_client_builder_1.McpTestClientBuilder; } });
12
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,qDAAkD;AAAzC,gHAAA,aAAa,OAAA;AACtB,qEAAiE;AAAxD,+HAAA,oBAAoB,OAAA","sourcesContent":["/**\n * @file client/index.ts\n * @description MCP Test Client exports\n */\n\nexport { McpTestClient } from './mcp-test-client';\nexport { McpTestClientBuilder } from './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 TransportState,\n // JSON-RPC types\n JSONRPCRequest,\n JSONRPCResponse,\n // Re-exports from MCP SDK\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} from './mcp-test-client.types';\n"]}