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:
Jerome 2025-07-10 16:52:32 +01:00
commit c6f3f40937
No known key found for this signature in database
5 changed files with 41 additions and 38 deletions

View file

@ -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();

View file

@ -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';

View file

@ -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;

View file

@ -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
});

View file

@ -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);
}