Skip to content

Commit 3bce26e

Browse files
committed
chore: fix lint
1 parent 1a3aab2 commit 3bce26e

File tree

5 files changed

+50
-35
lines changed

5 files changed

+50
-35
lines changed

scripts/generateArguments.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import { readFileSync, writeFileSync } from "fs";
1212
import { join, dirname } from "path";
1313
import { fileURLToPath } from "url";
1414
import { UserConfigSchema, configRegistry } from "../src/common/config/userConfig.js";
15-
import assert from "assert";
1615
import { execSync } from "child_process";
1716
import { OPTIONS } from "../src/common/config/argsParserOptions.js";
1817

@@ -69,12 +68,8 @@ function extractZodDescriptions(): Record<string, ConfigMetadata> {
6968
let description = schema.description || `Configuration option: ${key}`;
7069

7170
if ("innerType" in schema.def) {
72-
// "pipe" is used for our comma-separated arrays
71+
// "pipe" & innerType is assumed to be for our comma-separated arrays
7372
if (schema.def.innerType.def.type === "pipe") {
74-
assert(
75-
description.startsWith("An array of"),
76-
`Field description for field "${key}" with array type does not start with 'An array of'`
77-
);
7873
description = description.replace("An array of", "Comma separated values of");
7974
}
8075
}

src/common/config/configOverrides.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { UserConfig } from "./userConfig.js";
22
import { UserConfigSchema, configRegistry } from "./userConfig.js";
33
import type { RequestContext } from "../../transports/base.js";
4-
import type { OverrideBehavior } from "./configUtils.js";
4+
import type { ConfigFieldMeta, OverrideBehavior } from "./configUtils.js";
55

66
export const CONFIG_HEADER_PREFIX = "x-mongodb-mcp-";
77
export const CONFIG_QUERY_PREFIX = "mongodbMcp";
@@ -38,7 +38,7 @@ export function applyConfigOverrides({
3838
const behavior = getConfigMeta(key)?.overrideBehavior || "not-allowed";
3939
const baseValue = baseConfig[key as keyof UserConfig];
4040
const newValue = applyOverride(key, baseValue, overrideValue, behavior);
41-
(result as any)[key] = newValue;
41+
(result as Record<keyof UserConfig, unknown>)[key] = newValue;
4242
}
4343

4444
return result;
@@ -87,15 +87,15 @@ function assertValidConfigKey(key: string): asserts key is keyof typeof UserConf
8787
/**
8888
* Gets the schema metadata for a config key.
8989
*/
90-
export function getConfigMeta(key: keyof typeof UserConfigSchema.shape) {
90+
export function getConfigMeta(key: keyof typeof UserConfigSchema.shape): ConfigFieldMeta | undefined {
9191
return configRegistry.get(UserConfigSchema.shape[key]);
9292
}
9393

9494
/**
9595
* Parses a string value to the appropriate type using the Zod schema.
9696
*/
9797
function parseConfigValue(key: keyof typeof UserConfigSchema.shape, value: unknown): unknown {
98-
const fieldSchema = UserConfigSchema.shape[key as keyof typeof UserConfigSchema.shape];
98+
const fieldSchema = UserConfigSchema.shape[key];
9999
if (!fieldSchema) {
100100
throw new Error(`Invalid config key: ${key}`);
101101
}
@@ -114,7 +114,7 @@ export function nameToConfigKey(mode: "header" | "query", name: string): string
114114
if (mode === "header" && lowerCaseName.startsWith(CONFIG_HEADER_PREFIX)) {
115115
const normalized = lowerCaseName.substring(CONFIG_HEADER_PREFIX.length);
116116
// Convert kebab-case to camelCase
117-
return normalized.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
117+
return normalized.replace(/-([a-z])/g, (_, letter: string) => letter.toUpperCase());
118118
}
119119
if (mode === "query" && name.startsWith(CONFIG_QUERY_PREFIX)) {
120120
const withoutPrefix = name.substring(CONFIG_QUERY_PREFIX.length);
@@ -148,7 +148,7 @@ function applyOverride(
148148

149149
case "merge":
150150
if (Array.isArray(baseValue) && Array.isArray(overrideValue)) {
151-
return [...baseValue, ...overrideValue];
151+
return [...(baseValue as unknown[]), ...(overrideValue as unknown[])];
152152
}
153153
throw new Error("Cannot merge non-array values, did you mean to use the 'override' behavior?");
154154

tests/integration/transports/configOverrides.test.ts

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,26 @@ import { StreamableHttpRunner } from "../../../src/transports/streamableHttp.js"
22
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
33
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
44
import { describe, expect, it, afterEach, beforeEach } from "vitest";
5-
import { defaultTestConfig } from "../helpers.js";
5+
import { defaultTestConfig, expectDefined } from "../helpers.js";
6+
import type { TransportRunnerConfig, UserConfig } from "../../../src/lib.js";
7+
import type { RequestContext } from "../../../src/transports/base.js";
68

79
describe("Config Overrides via HTTP", () => {
810
let runner: StreamableHttpRunner;
911
let client: Client;
1012
let transport: StreamableHTTPClientTransport;
1113

1214
// Helper function to setup and start runner with config
13-
async function startRunner(config: any, createSessionConfig?: any) {
15+
async function startRunner(
16+
config: UserConfig,
17+
createSessionConfig?: TransportRunnerConfig["createSessionConfig"]
18+
): Promise<void> {
1419
runner = new StreamableHttpRunner({ userConfig: config, createSessionConfig });
1520
await runner.start();
1621
}
1722

1823
// Helper function to connect client with headers
19-
async function connectClient(headers: Record<string, string> = {}) {
24+
async function connectClient(headers: Record<string, string> = {}): Promise<void> {
2025
transport = new StreamableHTTPClientTransport(new URL(`${runner.serverAddress}/mcp`), {
2126
requestInit: { headers },
2227
});
@@ -106,7 +111,8 @@ describe("Config Overrides via HTTP", () => {
106111
const insertTool = response.tools.find(
107112
(tool) => tool.name === "insert-many" || tool.name === "find" || tool.name === "aggregate"
108113
);
109-
expect(response.tools).is.not.empty;
114+
115+
expect(response.tools).not.toHaveLength(0);
110116
expect(insertTool).toBeUndefined();
111117
});
112118
});
@@ -228,14 +234,15 @@ describe("Config Overrides via HTTP", () => {
228234

229235
// createSessionConfig receives the config after header overrides are applied
230236
// It can further modify it, but headers have already been applied
231-
const createSessionConfig = async ({
237+
const createSessionConfig: TransportRunnerConfig["createSessionConfig"] = ({
232238
userConfig: config,
233239
request,
234240
}: {
235241
userConfig: typeof userConfig;
236-
request?: any;
237-
}) => {
238-
expect(request).toBeDefined();
242+
request?: RequestContext;
243+
}): typeof userConfig => {
244+
expectDefined(request);
245+
expectDefined(request.headers);
239246
expect(request.headers).toBeDefined();
240247
config.readOnly = request.headers["x-mongodb-mcp-read-only"] === "true";
241248
config.disabledTools = ["count"];
@@ -260,7 +267,7 @@ describe("Config Overrides via HTTP", () => {
260267
const countTool = response.tools.find((tool) => tool.name === "count");
261268
expect(countTool).toBeUndefined();
262269

263-
expect(response.tools).is.not.empty;
270+
expect(response.tools).not.toHaveLength(0);
264271
});
265272

266273
it("should pass request context to createSessionConfig", async () => {
@@ -269,10 +276,17 @@ describe("Config Overrides via HTTP", () => {
269276
httpPort: 0,
270277
};
271278

272-
let capturedRequest: any;
273-
const createSessionConfig = async ({ request }: { userConfig: typeof userConfig; request?: any }) => {
279+
let capturedRequest: RequestContext | undefined;
280+
const createSessionConfig: TransportRunnerConfig["createSessionConfig"] = ({
281+
request,
282+
}: {
283+
userConfig: typeof userConfig;
284+
request?: RequestContext;
285+
}): Promise<typeof userConfig> => {
286+
expectDefined(request);
287+
expectDefined(request.headers);
274288
capturedRequest = request;
275-
return userConfig;
289+
return Promise.resolve(userConfig);
276290
};
277291

278292
await startRunner(userConfig, createSessionConfig);
@@ -282,7 +296,8 @@ describe("Config Overrides via HTTP", () => {
282296
});
283297

284298
// Verify that request context was passed
285-
expect(capturedRequest).toBeDefined();
299+
expectDefined(capturedRequest);
300+
expectDefined(capturedRequest.headers);
286301
expect(capturedRequest.headers["x-custom-header"]).toBe("test-value");
287302
});
288303
});

tests/integration/transports/createSessionConfig.test.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import { StreamableHttpRunner } from "../../../src/transports/streamableHttp.js"
22
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
33
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
44
import { afterEach, describe, expect, it } from "vitest";
5-
import type { TransportRunnerConfig } from "../../../src/lib.js";
6-
import { defaultTestConfig } from "../helpers.js";
5+
import type { TransportRunnerConfig, UserConfig } from "../../../src/lib.js";
6+
import { defaultTestConfig, expectDefined } from "../helpers.js";
77

88
describe("createSessionConfig", () => {
99
const userConfig = defaultTestConfig;
@@ -17,7 +17,7 @@ describe("createSessionConfig", () => {
1717
userConfig?: typeof userConfig;
1818
createSessionConfig?: TransportRunnerConfig["createSessionConfig"];
1919
} = {}
20-
) => {
20+
): Promise<StreamableHttpRunner> => {
2121
runner = new StreamableHttpRunner({
2222
userConfig: { ...userConfig, httpPort: 0, ...config.userConfig },
2323
createSessionConfig: config.createSessionConfig,
@@ -27,13 +27,13 @@ describe("createSessionConfig", () => {
2727
};
2828

2929
// Helper to setup server and get user config
30-
const getServerConfig = async () => {
30+
const getServerConfig = async (): Promise<UserConfig> => {
3131
const server = await runner["setupServer"]();
3232
return server.userConfig;
3333
};
3434

3535
// Helper to create and connect client
36-
const createConnectedClient = async () => {
36+
const createConnectedClient = async (): Promise<{ client: Client; transport: StreamableHTTPClientTransport }> => {
3737
client = new Client({ name: "test-client", version: "1.0.0" });
3838
transport = new StreamableHTTPClientTransport(new URL(`${runner.serverAddress}/mcp`));
3939
await client.connect(transport);
@@ -109,9 +109,9 @@ describe("createSessionConfig", () => {
109109
});
110110

111111
await createConnectedClient();
112-
const response = await client!.listTools();
112+
const response = await client?.listTools();
113+
expectDefined(response);
113114

114-
expect(response).toBeDefined();
115115
expect(response.tools).toBeDefined();
116116
expect(response.tools.length).toBeGreaterThan(0);
117117

tests/unit/common/config/configOverrides.test.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,9 @@ describe("configOverrides", () => {
144144
it("should have some not-allowed fields", () => {
145145
expect(
146146
Object.keys(UserConfigSchema.shape).filter(
147-
(key) => getConfigMeta(key as any)?.overrideBehavior === "not-allowed"
147+
(key) =>
148+
getConfigMeta(key as keyof typeof UserConfigSchema.shape)?.overrideBehavior ===
149+
"not-allowed"
148150
)
149151
).toEqual([
150152
"apiBaseUrl",
@@ -183,8 +185,11 @@ describe("configOverrides", () => {
183185
it("should have certain config keys to be conditionally overridden", () => {
184186
expect(
185187
Object.keys(UserConfigSchema.shape)
186-
.map((key) => [key, getConfigMeta(key as any)?.overrideBehavior])
187-
.filter(([_, behavior]) => typeof behavior === "function")
188+
.map((key) => [
189+
key,
190+
getConfigMeta(key as keyof typeof UserConfigSchema.shape)?.overrideBehavior,
191+
])
192+
.filter(([, behavior]) => typeof behavior === "function")
188193
.map(([key]) => key)
189194
).toEqual(["readOnly", "indexCheck", "disableEmbeddingsValidation"]);
190195
});

0 commit comments

Comments
 (0)