Fix all ESLint errors
- Remove unused imports and variables - Replace 'any' types with proper type guards - Add comments to empty catch blocks - Fix Response/Request type imports in logger - Use 'unknown' instead of 'any' for generic types - Remove unused createMcpServer and setSessionOwner imports All ESLint checks now pass. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
e13aefc8c4
commit
c6f3f40937
5 changed files with 41 additions and 38 deletions
|
|
@ -1,10 +1,10 @@
|
|||
import { jest } from '@jest/globals';
|
||||
import { Request, Response } from 'express';
|
||||
import { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';
|
||||
import { JSONRPCMessage, JSONRPCResponse } from '@modelcontextprotocol/sdk/types.js';
|
||||
import { MockRedisClient, setRedisClient } from '../redis.js';
|
||||
import { handleStreamableHTTP } from './shttp.js';
|
||||
import { AuthInfo } from '@modelcontextprotocol/sdk/server/auth/types.js';
|
||||
import { randomUUID } from 'crypto';
|
||||
// import { randomUUID } from 'crypto'; // Currently unused but may be needed for future tests
|
||||
import { shutdownSession } from '../services/redisTransport.js';
|
||||
|
||||
describe('Streamable HTTP Handler Integration Tests', () => {
|
||||
|
|
@ -147,7 +147,6 @@ describe('Streamable HTTP Handler Integration Tests', () => {
|
|||
});
|
||||
|
||||
it('should handle cleanup errors gracefully', async () => {
|
||||
const sessionId = randomUUID();
|
||||
const initRequest: JSONRPCMessage = {
|
||||
jsonrpc: '2.0',
|
||||
id: 'init-1',
|
||||
|
|
@ -176,7 +175,6 @@ describe('Streamable HTTP Handler Integration Tests', () => {
|
|||
)?.[1] as (() => Promise<void>) | undefined;
|
||||
|
||||
// Simulate error during cleanup
|
||||
const originalSimulateError = mockRedis.simulateError.bind(mockRedis);
|
||||
|
||||
// Cleanup should not throw error even if Redis operations fail
|
||||
if (finishHandler) {
|
||||
|
|
@ -240,7 +238,7 @@ describe('Streamable HTTP Handler Integration Tests', () => {
|
|||
let sessionId: string | undefined;
|
||||
|
||||
if (jsonCalls.length > 0) {
|
||||
const response = jsonCalls[0][0] as any;
|
||||
const response = jsonCalls[0][0] as JSONRPCResponse;
|
||||
if (response?.result?._meta?.sessionId) {
|
||||
sessionId = response.result._meta.sessionId;
|
||||
}
|
||||
|
|
@ -254,11 +252,11 @@ describe('Streamable HTTP Handler Integration Tests', () => {
|
|||
try {
|
||||
// SSE data format: "data: {...}\n\n"
|
||||
const jsonStr = data.replace(/^data: /, '').trim();
|
||||
const parsed = JSON.parse(jsonStr) as any;
|
||||
const parsed = JSON.parse(jsonStr) as JSONRPCResponse;
|
||||
if (parsed?.result?._meta?.sessionId) {
|
||||
sessionId = parsed.result._meta.sessionId;
|
||||
}
|
||||
} catch (e) {
|
||||
} catch {
|
||||
// Not valid JSON, continue
|
||||
}
|
||||
}
|
||||
|
|
@ -344,7 +342,7 @@ describe('Streamable HTTP Handler Integration Tests', () => {
|
|||
// Check JSON responses
|
||||
const jsonCalls = (mockRes.json as jest.Mock).mock.calls;
|
||||
if (jsonCalls.length > 0) {
|
||||
const response = jsonCalls[0][0] as any;
|
||||
const response = jsonCalls[0][0] as JSONRPCResponse;
|
||||
if (response?.result?._meta?.sessionId) {
|
||||
sessionId = response.result._meta.sessionId;
|
||||
}
|
||||
|
|
@ -357,11 +355,13 @@ describe('Streamable HTTP Handler Integration Tests', () => {
|
|||
if (typeof data === 'string' && data.includes('sessionId')) {
|
||||
try {
|
||||
const jsonStr = data.replace(/^data: /, '').trim();
|
||||
const parsed = JSON.parse(jsonStr) as any;
|
||||
const parsed = JSON.parse(jsonStr) as JSONRPCResponse;
|
||||
if (parsed?.result?._meta?.sessionId) {
|
||||
sessionId = parsed.result._meta.sessionId;
|
||||
}
|
||||
} catch (e) {}
|
||||
} catch {
|
||||
// Ignore JSON parse errors
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -442,7 +442,7 @@ describe('Streamable HTTP Handler Integration Tests', () => {
|
|||
// Check JSON responses
|
||||
const jsonCalls = (mockRes.json as jest.Mock).mock.calls;
|
||||
if (jsonCalls.length > 0) {
|
||||
const response = jsonCalls[0][0] as any;
|
||||
const response = jsonCalls[0][0] as JSONRPCResponse;
|
||||
if (response?.result?._meta?.sessionId) {
|
||||
actualSessionId = response.result._meta.sessionId;
|
||||
}
|
||||
|
|
@ -459,7 +459,9 @@ describe('Streamable HTTP Handler Integration Tests', () => {
|
|||
if (parsed?.result?._meta?.sessionId) {
|
||||
actualSessionId = parsed.result._meta.sessionId;
|
||||
}
|
||||
} catch (e) {}
|
||||
} catch {
|
||||
// Ignore JSON parse errors
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -658,8 +660,7 @@ describe('Streamable HTTP Handler Integration Tests', () => {
|
|||
await finishHandler2();
|
||||
}
|
||||
|
||||
// Track session 2 ID
|
||||
const session2Id = 'user2-session-id';
|
||||
// Track session 2 ID (placeholder for actual implementation)
|
||||
|
||||
// User 1 deletes their session
|
||||
jest.clearAllMocks();
|
||||
|
|
|
|||
|
|
@ -4,8 +4,7 @@ import { MockRedisClient, setRedisClient } from '../redis.js';
|
|||
import {
|
||||
ServerRedisTransport,
|
||||
redisRelayToMcpServer,
|
||||
shutdownSession,
|
||||
setSessionOwner
|
||||
shutdownSession
|
||||
} from './redisTransport.js';
|
||||
import { createMcpServer } from './mcp.js';
|
||||
import { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import {
|
|||
isSessionOwnedBy
|
||||
} from './redisTransport.js';
|
||||
import { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
|
||||
import { createMcpServer } from './mcp.js';
|
||||
|
||||
describe('Redis Transport', () => {
|
||||
let mockRedis: MockRedisClient;
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@ function sendToMcpServer(sessionId: string, message: JSONRPCMessage, extra?: { a
|
|||
logger.debug('Sending message to MCP server via Redis', {
|
||||
sessionId,
|
||||
channel: toServerChannel,
|
||||
method: (message as any).method,
|
||||
id: (message as any).id
|
||||
method: ('method' in message ? message.method : undefined),
|
||||
id: ('id' in message ? message.id : undefined)
|
||||
});
|
||||
|
||||
const redisMessage: RedisMessage = { type: 'mcp', message, extra, options };
|
||||
|
|
@ -125,7 +125,7 @@ export async function redisRelayToMcpServer(sessionId: string, transport: Transp
|
|||
logger.debug('Relaying message from Redis to client', {
|
||||
sessionId,
|
||||
requestId,
|
||||
method: (redisMessage.message as any).method
|
||||
method: ('method' in redisMessage.message ? redisMessage.message.method : undefined)
|
||||
});
|
||||
await transport.send(redisMessage.message, redisMessage.options);
|
||||
}
|
||||
|
|
@ -148,7 +148,7 @@ export async function redisRelayToMcpServer(sessionId: string, transport: Transp
|
|||
logger.debug('Setting up response subscription', {
|
||||
sessionId,
|
||||
messageId: message.id,
|
||||
method: (message as any).method
|
||||
method: ('method' in message ? message.method : undefined)
|
||||
});
|
||||
await subscribe(message.id.toString());
|
||||
}
|
||||
|
|
@ -235,8 +235,8 @@ export class ServerRedisTransport implements Transport {
|
|||
|
||||
logger.debug('Received MCP message from client', {
|
||||
sessionId: this._sessionId,
|
||||
method: (redisMessage.message as any).method,
|
||||
id: (redisMessage.message as any).id
|
||||
method: ('method' in redisMessage.message ? redisMessage.message.method : undefined),
|
||||
id: ('id' in redisMessage.message ? redisMessage.message.id : undefined)
|
||||
});
|
||||
|
||||
this.onmessage?.(redisMessage.message, redisMessage.extra);
|
||||
|
|
@ -295,8 +295,8 @@ export class ServerRedisTransport implements Transport {
|
|||
logger.debug('Sending message to client', {
|
||||
sessionId: this._sessionId,
|
||||
channel,
|
||||
method: (message as any).method,
|
||||
id: (message as any).id,
|
||||
method: ('method' in message ? message.method : undefined),
|
||||
id: ('id' in message ? message.id : undefined),
|
||||
relatedRequestId
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { AsyncLocalStorage } from 'async_hooks';
|
||||
import { Request } from 'express';
|
||||
import { Request, Response, NextFunction } from 'express';
|
||||
|
||||
// Severity levels as per Google Cloud Logging
|
||||
export enum LogSeverity {
|
||||
|
|
@ -17,7 +17,11 @@ export enum LogSeverity {
|
|||
interface LogContext {
|
||||
trace?: string;
|
||||
spanId?: string;
|
||||
[key: string]: any;
|
||||
requestId?: string;
|
||||
userAgent?: string;
|
||||
method?: string;
|
||||
path?: string;
|
||||
[key: string]: string | undefined;
|
||||
}
|
||||
|
||||
interface StructuredLogEntry {
|
||||
|
|
@ -26,7 +30,7 @@ interface StructuredLogEntry {
|
|||
timestamp: string;
|
||||
'logging.googleapis.com/trace'?: string;
|
||||
'logging.googleapis.com/spanId'?: string;
|
||||
[key: string]: any;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
class StructuredLogger {
|
||||
|
|
@ -73,7 +77,7 @@ class StructuredLogger {
|
|||
* Create Express middleware for request context
|
||||
*/
|
||||
middleware() {
|
||||
return (req: Request, res: any, next: any) => {
|
||||
return (req: Request, res: Response, next: NextFunction) => {
|
||||
const context = this.extractTraceContext(req);
|
||||
this.runWithContext(context, () => {
|
||||
next();
|
||||
|
|
@ -84,7 +88,7 @@ class StructuredLogger {
|
|||
/**
|
||||
* Log a structured message
|
||||
*/
|
||||
private log(severity: LogSeverity, message: string, metadata?: Record<string, any>) {
|
||||
private log(severity: LogSeverity, message: string, metadata?: Record<string, unknown>) {
|
||||
const context = this.asyncLocalStorage.getStore() || {};
|
||||
|
||||
const entry: StructuredLogEntry = {
|
||||
|
|
@ -114,23 +118,23 @@ class StructuredLogger {
|
|||
}
|
||||
|
||||
// Convenience methods for different severity levels
|
||||
debug(message: string, metadata?: Record<string, any>) {
|
||||
debug(message: string, metadata?: Record<string, unknown>) {
|
||||
this.log(LogSeverity.DEBUG, message, metadata);
|
||||
}
|
||||
|
||||
info(message: string, metadata?: Record<string, any>) {
|
||||
info(message: string, metadata?: Record<string, unknown>) {
|
||||
this.log(LogSeverity.INFO, message, metadata);
|
||||
}
|
||||
|
||||
notice(message: string, metadata?: Record<string, any>) {
|
||||
notice(message: string, metadata?: Record<string, unknown>) {
|
||||
this.log(LogSeverity.NOTICE, message, metadata);
|
||||
}
|
||||
|
||||
warning(message: string, metadata?: Record<string, any>) {
|
||||
warning(message: string, metadata?: Record<string, unknown>) {
|
||||
this.log(LogSeverity.WARNING, message, metadata);
|
||||
}
|
||||
|
||||
error(message: string, error?: Error, metadata?: Record<string, any>) {
|
||||
error(message: string, error?: Error, metadata?: Record<string, unknown>) {
|
||||
const errorMetadata = {
|
||||
...metadata,
|
||||
error: error ? {
|
||||
|
|
@ -142,15 +146,15 @@ class StructuredLogger {
|
|||
this.log(LogSeverity.ERROR, message, errorMetadata);
|
||||
}
|
||||
|
||||
critical(message: string, metadata?: Record<string, any>) {
|
||||
critical(message: string, metadata?: Record<string, unknown>) {
|
||||
this.log(LogSeverity.CRITICAL, message, metadata);
|
||||
}
|
||||
|
||||
alert(message: string, metadata?: Record<string, any>) {
|
||||
alert(message: string, metadata?: Record<string, unknown>) {
|
||||
this.log(LogSeverity.ALERT, message, metadata);
|
||||
}
|
||||
|
||||
emergency(message: string, metadata?: Record<string, any>) {
|
||||
emergency(message: string, metadata?: Record<string, unknown>) {
|
||||
this.log(LogSeverity.EMERGENCY, message, metadata);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue