refactor: satisfy oxlint rules
This commit is contained in:
parent
efed4d4383
commit
9bfc604e01
@ -5,68 +5,62 @@
|
||||
* and print only the markdown headlines.
|
||||
*/
|
||||
|
||||
import { createRuntime, createServerProxy, type CallResult } from "../src/index.js";
|
||||
import { createRuntime, createServerProxy, type CallResult } from '../src/index.js';
|
||||
|
||||
async function main(): Promise<void> {
|
||||
const apiKey = process.env.CONTEXT7_API_KEY;
|
||||
const context7Definition = {
|
||||
name: "context7",
|
||||
description: "Context7 documentation MCP",
|
||||
command: {
|
||||
kind: "http" as const,
|
||||
url: new URL("https://mcp.context7.com/mcp"),
|
||||
headers: apiKey ? { Authorization: `Bearer ${apiKey}` } : undefined,
|
||||
},
|
||||
};
|
||||
// Inline definitions can also live in config/mcporter.json if you prefer shared config.
|
||||
const apiKey = process.env.CONTEXT7_API_KEY;
|
||||
const context7Definition = {
|
||||
name: 'context7',
|
||||
description: 'Context7 documentation MCP',
|
||||
command: {
|
||||
kind: 'http' as const,
|
||||
url: new URL('https://mcp.context7.com/mcp'),
|
||||
headers: apiKey ? { Authorization: `Bearer ${apiKey}` } : undefined,
|
||||
},
|
||||
};
|
||||
// Inline definitions can also live in config/mcporter.json if you prefer shared config.
|
||||
|
||||
const mcpRuntime = await createRuntime({ servers: [context7Definition] });
|
||||
try {
|
||||
const context7 = createServerProxy(mcpRuntime, "context7") as Record<string, unknown>;
|
||||
const resolveLibraryId = context7.resolveLibraryId as (
|
||||
args: unknown,
|
||||
) => Promise<CallResult>;
|
||||
const getLibraryDocs = context7.getLibraryDocs as (
|
||||
args: unknown,
|
||||
) => Promise<CallResult>;
|
||||
const mcpRuntime = await createRuntime({ servers: [context7Definition] });
|
||||
try {
|
||||
const context7 = createServerProxy(mcpRuntime, 'context7') as Record<string, unknown>;
|
||||
const resolveLibraryId = context7.resolveLibraryId as (args: unknown) => Promise<CallResult>;
|
||||
const getLibraryDocs = context7.getLibraryDocs as (args: unknown) => Promise<CallResult>;
|
||||
|
||||
const resolved = await resolveLibraryId("react");
|
||||
const contextId = extractContext7LibraryId(resolved);
|
||||
if (!contextId) {
|
||||
throw new Error("Unable to resolve React documentation ID from Context7.");
|
||||
}
|
||||
const resolved = await resolveLibraryId('react');
|
||||
const contextId = extractContext7LibraryId(resolved);
|
||||
if (!contextId) {
|
||||
throw new Error('Unable to resolve React documentation ID from Context7.');
|
||||
}
|
||||
|
||||
const docs = await getLibraryDocs(contextId);
|
||||
const docs = await getLibraryDocs(contextId);
|
||||
|
||||
const markdown = docs.markdown() ?? docs.text() ?? "";
|
||||
const headlines = markdown
|
||||
.split("\n")
|
||||
.filter((line) => /^#+\s/.test(line))
|
||||
.join("\n");
|
||||
const markdown = docs.markdown() ?? docs.text() ?? '';
|
||||
const headlines = markdown
|
||||
.split('\n')
|
||||
.filter((line) => /^#+\s/.test(line))
|
||||
.join('\n');
|
||||
|
||||
console.log("# Headlines for React");
|
||||
console.log(headlines || "(no headlines found)");
|
||||
} finally {
|
||||
await mcpRuntime.close();
|
||||
}
|
||||
console.log('# Headlines for React');
|
||||
console.log(headlines || '(no headlines found)');
|
||||
} finally {
|
||||
await mcpRuntime.close();
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
function extractContext7LibraryId(result: CallResult): string | null {
|
||||
const json = result.json<
|
||||
{ candidates?: Array<{ context7CompatibleLibraryID?: string }> } | undefined
|
||||
>();
|
||||
if (json && json.candidates) {
|
||||
for (const candidate of json.candidates) {
|
||||
if (candidate?.context7CompatibleLibraryID) {
|
||||
return candidate.context7CompatibleLibraryID;
|
||||
}
|
||||
}
|
||||
}
|
||||
const textMatch = result.text()?.match(/Context7-compatible library ID:\s*([^\s]+)/);
|
||||
return textMatch?.[1] ?? null;
|
||||
const json = result.json<{ candidates?: Array<{ context7CompatibleLibraryID?: string }> } | undefined>();
|
||||
if (json && json.candidates) {
|
||||
for (const candidate of json.candidates) {
|
||||
if (candidate?.context7CompatibleLibraryID) {
|
||||
return candidate.context7CompatibleLibraryID;
|
||||
}
|
||||
}
|
||||
}
|
||||
const textMatch = result.text()?.match(/Context7-compatible library ID:\s*([^\s]+)/);
|
||||
return textMatch?.[1] ?? null;
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ function walkMarkdownFiles(dir: string, base: string = dir): string[] {
|
||||
files.push(relative(base, fullPath));
|
||||
}
|
||||
}
|
||||
return files.sort((a, b) => a.localeCompare(b));
|
||||
return files.toSorted((a, b) => a.localeCompare(b));
|
||||
}
|
||||
|
||||
function extractMetadata(fullPath: string): {
|
||||
|
||||
@ -80,7 +80,7 @@ export async function handleAuth(runtime: Runtime, args: string[]): Promise<void
|
||||
process.exitCode = 1;
|
||||
return;
|
||||
}
|
||||
throw new Error(`Failed to authorize '${target}': ${message}`);
|
||||
throw new Error(`Failed to authorize '${target}': ${message}`, { cause: error });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -284,7 +284,7 @@ function handleArgsFlag(context: FlagHandlerContext): number {
|
||||
try {
|
||||
decoded = JSON.parse(raw);
|
||||
} catch (error) {
|
||||
throw new Error(`Unable to parse --args: ${(error as Error).message}`);
|
||||
throw new Error(`Unable to parse --args: ${(error as Error).message}`, { cause: error });
|
||||
}
|
||||
if (decoded === null || typeof decoded !== 'object' || Array.isArray(decoded)) {
|
||||
throw new Error('Unable to parse --args: --args must be a JSON object.');
|
||||
|
||||
@ -25,7 +25,7 @@ import { dimText, redText, yellowText } from './terminal.js';
|
||||
import { resolveCallTimeout, withTimeout } from './timeouts.js';
|
||||
import { loadToolMetadata } from './tool-cache.js';
|
||||
|
||||
type Runtime = Awaited<ReturnType<typeof import('../runtime.js')['createRuntime']>>;
|
||||
type Runtime = Awaited<ReturnType<(typeof import('../runtime.js'))['createRuntime']>>;
|
||||
|
||||
interface ResolvedCallTarget {
|
||||
server: string;
|
||||
@ -199,7 +199,7 @@ export function printCallHelp(): void {
|
||||
}
|
||||
|
||||
async function maybeDescribeServer(
|
||||
runtime: Awaited<ReturnType<typeof import('../runtime.js')['createRuntime']>>,
|
||||
runtime: Awaited<ReturnType<(typeof import('../runtime.js'))['createRuntime']>>,
|
||||
server: string,
|
||||
tool: string,
|
||||
outputFormat: OutputFormat
|
||||
@ -266,7 +266,7 @@ function resolveCallTarget(
|
||||
}
|
||||
|
||||
async function enforceSchemaStringTypes(
|
||||
runtime: Awaited<ReturnType<typeof import('../runtime.js')['createRuntime']>>,
|
||||
runtime: Awaited<ReturnType<(typeof import('../runtime.js'))['createRuntime']>>,
|
||||
server: string,
|
||||
tool: string,
|
||||
args: Record<string, unknown>,
|
||||
@ -325,7 +325,7 @@ function schemaAllowsString(descriptor: unknown): boolean {
|
||||
}
|
||||
|
||||
async function hydratePositionalArguments(
|
||||
runtime: Awaited<ReturnType<typeof import('../runtime.js')['createRuntime']>>,
|
||||
runtime: Awaited<ReturnType<(typeof import('../runtime.js'))['createRuntime']>>,
|
||||
server: string,
|
||||
tool: string,
|
||||
namedArgs: Record<string, unknown>,
|
||||
@ -375,7 +375,7 @@ async function hydratePositionalArguments(
|
||||
type ToolResolution = IdentifierResolution;
|
||||
|
||||
async function inferSingleToolName(
|
||||
runtime: Awaited<ReturnType<typeof import('../runtime.js')['createRuntime']>>,
|
||||
runtime: Awaited<ReturnType<(typeof import('../runtime.js'))['createRuntime']>>,
|
||||
server: string
|
||||
): Promise<string | undefined> {
|
||||
const tools = await loadToolMetadata(runtime, server, { includeSchema: false });
|
||||
@ -391,7 +391,7 @@ async function inferSingleToolName(
|
||||
}
|
||||
|
||||
async function invokeWithAutoCorrection(
|
||||
runtime: Awaited<ReturnType<typeof import('../runtime.js')['createRuntime']>>,
|
||||
runtime: Awaited<ReturnType<(typeof import('../runtime.js'))['createRuntime']>>,
|
||||
server: string,
|
||||
tool: string,
|
||||
args: Record<string, unknown>,
|
||||
@ -402,7 +402,7 @@ async function invokeWithAutoCorrection(
|
||||
}
|
||||
|
||||
async function attemptCall(
|
||||
runtime: Awaited<ReturnType<typeof import('../runtime.js')['createRuntime']>>,
|
||||
runtime: Awaited<ReturnType<(typeof import('../runtime.js'))['createRuntime']>>,
|
||||
server: string,
|
||||
tool: string,
|
||||
args: Record<string, unknown>,
|
||||
@ -417,7 +417,8 @@ async function attemptCall(
|
||||
const timeoutDisplay = `${timeoutMs}ms`;
|
||||
await runtime.close(server).catch(() => {});
|
||||
throw new Error(
|
||||
`Call to ${server}.${tool} timed out after ${timeoutDisplay}. Override MCPORTER_CALL_TIMEOUT or pass --timeout to adjust.`
|
||||
`Call to ${server}.${tool} timed out after ${timeoutDisplay}. Override MCPORTER_CALL_TIMEOUT or pass --timeout to adjust.`,
|
||||
{ cause: error }
|
||||
);
|
||||
}
|
||||
|
||||
@ -451,7 +452,7 @@ async function attemptCall(
|
||||
}
|
||||
|
||||
async function maybeResolveToolName(
|
||||
runtime: Awaited<ReturnType<typeof import('../runtime.js')['createRuntime']>>,
|
||||
runtime: Awaited<ReturnType<(typeof import('../runtime.js'))['createRuntime']>>,
|
||||
server: string,
|
||||
attemptedTool: string,
|
||||
error: unknown
|
||||
|
||||
@ -202,7 +202,7 @@ function parseTransport(value: string | undefined): 'http' | 'sse' | 'stdio' {
|
||||
}
|
||||
|
||||
function parseKeyValue(input: string | undefined, target: Record<string, string>, flagName: string): void {
|
||||
if (!input || !input.includes('=')) {
|
||||
if (!input?.includes('=')) {
|
||||
throw new CliUsageError(`${flagName} requires KEY=value.`);
|
||||
}
|
||||
const [key, ...rest] = input.split('=');
|
||||
|
||||
@ -26,8 +26,8 @@ export function cloneConfig(config: RawConfig): RawConfig {
|
||||
|
||||
export async function loadOrCreateConfig(loadOptions: LoadConfigOptions): Promise<{ config: RawConfig; path: string }> {
|
||||
try {
|
||||
const { config, path } = await loadRawConfig(loadOptions);
|
||||
return { config, path };
|
||||
const { config, path: configPath } = await loadRawConfig(loadOptions);
|
||||
return { config, path: configPath };
|
||||
} catch (error) {
|
||||
if (isErrno(error, 'ENOENT')) {
|
||||
const rootDir = loadOptions.rootDir ?? process.cwd();
|
||||
|
||||
@ -182,7 +182,7 @@ function getServerDefinition(runtime: Runtime, selector: string): ServerDefiniti
|
||||
return runtime.getDefinition(resolved);
|
||||
}
|
||||
if (error instanceof Error) {
|
||||
throw new Error(error.message);
|
||||
throw new Error(error.message, { cause: error });
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
|
||||
@ -66,7 +66,7 @@ export function extractEphemeralServerFlags(
|
||||
|
||||
if (token === '--env') {
|
||||
const value = args[index + 1];
|
||||
if (!value || !value.includes('=')) {
|
||||
if (!value?.includes('=')) {
|
||||
throw new Error("Flag '--env' requires KEY=value.");
|
||||
}
|
||||
const [key, ...rest] = value.split('=');
|
||||
|
||||
@ -46,7 +46,7 @@ async function bundleWithRolldown({
|
||||
runtimeKind: 'node' | 'bun';
|
||||
minify: boolean;
|
||||
}): Promise<string> {
|
||||
let rolldownImpl: typeof import('rolldown')['rolldown'];
|
||||
let rolldownImpl: (typeof import('rolldown'))['rolldown'];
|
||||
try {
|
||||
({ rolldown: rolldownImpl } = await import('rolldown'));
|
||||
} catch (error) {
|
||||
@ -56,7 +56,7 @@ async function bundleWithRolldown({
|
||||
error.message = `${message}\n\n${error.message}`;
|
||||
throw error;
|
||||
}
|
||||
throw new Error(message);
|
||||
throw new Error(message, { cause: error });
|
||||
}
|
||||
const absTarget = path.resolve(targetPath);
|
||||
await fs.mkdir(path.dirname(absTarget), { recursive: true });
|
||||
|
||||
@ -167,8 +167,7 @@ function deriveNameFromUrl(url: URL): string | undefined {
|
||||
return last;
|
||||
}
|
||||
}
|
||||
const segments = url.pathname.split('/').filter(Boolean);
|
||||
const firstSegment = segments[0];
|
||||
const firstSegment = url.pathname.split('/').find(Boolean);
|
||||
if (firstSegment) {
|
||||
return firstSegment.replace(/[^a-zA-Z0-9-_]/g, '-');
|
||||
}
|
||||
|
||||
@ -79,11 +79,12 @@ export function renderTemplate({
|
||||
flagExtras: [{ text: '--raw <json>' }],
|
||||
}),
|
||||
}));
|
||||
const renderedTools = toolDocs.map((entry) => ({
|
||||
...renderToolCommand(entry.tool, timeoutMs, serverName, entry.doc),
|
||||
doc: entry.doc,
|
||||
tool: entry.tool,
|
||||
}));
|
||||
const renderedTools = toolDocs.map((entry) =>
|
||||
Object.assign(renderToolCommand(entry.tool, timeoutMs, serverName, entry.doc), {
|
||||
doc: entry.doc,
|
||||
tool: entry.tool,
|
||||
})
|
||||
);
|
||||
const toolHelp = renderedTools.map((entry) => ({
|
||||
name: entry.commandName,
|
||||
description: entry.tool.tool.description ?? '',
|
||||
|
||||
@ -20,6 +20,26 @@ export interface GeneratedOption {
|
||||
formatHint?: string;
|
||||
}
|
||||
|
||||
function resolveSchemaType(value: unknown): GeneratedOption['type'] | undefined {
|
||||
if (value === 'integer') {
|
||||
return 'number';
|
||||
}
|
||||
if (value === 'string' || value === 'number' || value === 'boolean' || value === 'array' || value === 'object') {
|
||||
return value;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function resolveArrayItemType(value: unknown): GeneratedOption['arrayItemType'] | undefined {
|
||||
if (value === 'integer') {
|
||||
return 'number';
|
||||
}
|
||||
if (value === 'string' || value === 'number' || value === 'boolean') {
|
||||
return value;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function buildToolMetadata(tool: ServerToolInfo): ToolMetadata {
|
||||
const methodName = toProxyMethodName(tool.name);
|
||||
const properties = extractOptions(tool);
|
||||
@ -230,25 +250,16 @@ export function inferType(descriptor: unknown): GeneratedOption['type'] {
|
||||
return 'unknown';
|
||||
}
|
||||
const type = (descriptor as Record<string, unknown>).type;
|
||||
const resolveType = (value: unknown): GeneratedOption['type'] | undefined => {
|
||||
if (value === 'integer') {
|
||||
return 'number';
|
||||
}
|
||||
if (value === 'string' || value === 'number' || value === 'boolean' || value === 'array' || value === 'object') {
|
||||
return value;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
if (Array.isArray(type)) {
|
||||
for (const entry of type) {
|
||||
const resolved = resolveType(entry);
|
||||
const resolved = resolveSchemaType(entry);
|
||||
if (resolved) {
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
return 'unknown';
|
||||
}
|
||||
const resolved = resolveType(type);
|
||||
const resolved = resolveSchemaType(type);
|
||||
if (resolved) {
|
||||
return resolved;
|
||||
}
|
||||
@ -265,25 +276,16 @@ export function inferArrayItemType(descriptor: unknown): GeneratedOption['arrayI
|
||||
}
|
||||
const items = record.items as Record<string, unknown>;
|
||||
const itemType = items.type;
|
||||
const resolveItemType = (value: unknown): GeneratedOption['arrayItemType'] | undefined => {
|
||||
if (value === 'integer') {
|
||||
return 'number';
|
||||
}
|
||||
if (value === 'string' || value === 'number' || value === 'boolean') {
|
||||
return value;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
if (Array.isArray(itemType)) {
|
||||
for (const entry of itemType) {
|
||||
const resolved = resolveItemType(entry);
|
||||
const resolved = resolveArrayItemType(entry);
|
||||
if (resolved) {
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
return 'unknown';
|
||||
}
|
||||
const resolved = resolveItemType(itemType);
|
||||
const resolved = resolveArrayItemType(itemType);
|
||||
if (resolved) {
|
||||
return resolved;
|
||||
}
|
||||
|
||||
@ -86,7 +86,7 @@ export function extractListFlags(args: string[]): {
|
||||
type ListOutputFormat = 'text' | 'json';
|
||||
|
||||
export async function handleList(
|
||||
runtime: Awaited<ReturnType<typeof import('../runtime.js')['createRuntime']>>,
|
||||
runtime: Awaited<ReturnType<(typeof import('../runtime.js'))['createRuntime']>>,
|
||||
args: string[]
|
||||
): Promise<void> {
|
||||
const flags = extractListFlags(args);
|
||||
@ -341,7 +341,6 @@ export async function handleList(
|
||||
const durationMs = Date.now() - startedAt;
|
||||
printSingleServerHeader(definition, undefined, durationMs, transportSummary, sourcePath);
|
||||
const message = error instanceof Error ? error.message : 'Failed to load tool list.';
|
||||
const timeoutMs = flags.timeoutMs ?? LIST_TIMEOUT_MS;
|
||||
const authCommand = buildAuthCommandHint(definition);
|
||||
const advice = classifyListError(error, definition.name, timeoutMs, { authCommand });
|
||||
console.warn(` Tools: <timed out after ${timeoutMs}ms>`);
|
||||
@ -390,7 +389,7 @@ export function printListHelp(): void {
|
||||
}
|
||||
|
||||
function resolveServerDefinition(
|
||||
runtime: Awaited<ReturnType<typeof import('../runtime.js')['createRuntime']>>,
|
||||
runtime: Awaited<ReturnType<(typeof import('../runtime.js'))['createRuntime']>>,
|
||||
name: string
|
||||
): { definition: ServerDefinition; name: string } | undefined {
|
||||
try {
|
||||
@ -423,7 +422,7 @@ function resolveServerDefinition(
|
||||
}
|
||||
|
||||
function suggestServerName(
|
||||
runtime: Awaited<ReturnType<typeof import('../runtime.js')['createRuntime']>>,
|
||||
runtime: Awaited<ReturnType<(typeof import('../runtime.js'))['createRuntime']>>,
|
||||
attempted: string
|
||||
) {
|
||||
const definitions = runtime.getDefinitions();
|
||||
|
||||
@ -33,7 +33,7 @@ export interface ListJsonServerEntry {
|
||||
}
|
||||
|
||||
export function printSingleServerHeader(
|
||||
definition: ReturnType<Awaited<ReturnType<typeof import('../runtime.js')['createRuntime']>>['getDefinition']>,
|
||||
definition: ReturnType<Awaited<ReturnType<(typeof import('../runtime.js'))['createRuntime']>>['getDefinition']>,
|
||||
toolCount: number | undefined,
|
||||
durationMs: number | undefined,
|
||||
transportSummary: string,
|
||||
@ -70,7 +70,7 @@ export function printSingleServerHeader(
|
||||
}
|
||||
|
||||
export function printToolDetail(
|
||||
definition: ReturnType<Awaited<ReturnType<typeof import('../runtime.js')['createRuntime']>>['getDefinition']>,
|
||||
definition: ReturnType<Awaited<ReturnType<(typeof import('../runtime.js'))['createRuntime']>>['getDefinition']>,
|
||||
metadata: ToolMetadata,
|
||||
includeSchema: boolean,
|
||||
requiredOnly: boolean
|
||||
@ -107,7 +107,7 @@ export function printToolDetail(
|
||||
}
|
||||
|
||||
function buildExampleOptions(
|
||||
definition: ReturnType<Awaited<ReturnType<typeof import('../runtime.js')['createRuntime']>>['getDefinition']>
|
||||
definition: ReturnType<Awaited<ReturnType<(typeof import('../runtime.js'))['createRuntime']>>['getDefinition']>
|
||||
): { selector?: string; wrapExpression?: boolean } | undefined {
|
||||
if (definition.source?.kind !== 'local' || definition.source.path !== '<adhoc>') {
|
||||
return undefined;
|
||||
@ -150,7 +150,7 @@ export function buildJsonListEntry(
|
||||
description: result.server.description,
|
||||
transport: formatTransportSummary(
|
||||
result.server as ReturnType<
|
||||
Awaited<ReturnType<typeof import('../runtime.js')['createRuntime']>>['getDefinition']
|
||||
Awaited<ReturnType<(typeof import('../runtime.js'))['createRuntime']>>['getDefinition']
|
||||
>
|
||||
),
|
||||
source: result.server.source,
|
||||
@ -164,7 +164,7 @@ export function buildJsonListEntry(
|
||||
};
|
||||
}
|
||||
const authCommand = buildAuthCommandHint(
|
||||
result.server as ReturnType<Awaited<ReturnType<typeof import('../runtime.js')['createRuntime']>>['getDefinition']>
|
||||
result.server as ReturnType<Awaited<ReturnType<(typeof import('../runtime.js'))['createRuntime']>>['getDefinition']>
|
||||
);
|
||||
const advice = classifyListError(result.error, result.server.name, timeoutSeconds, { authCommand });
|
||||
return {
|
||||
@ -173,7 +173,9 @@ export function buildJsonListEntry(
|
||||
durationMs: result.durationMs,
|
||||
description: result.server.description,
|
||||
transport: formatTransportSummary(
|
||||
result.server as ReturnType<Awaited<ReturnType<typeof import('../runtime.js')['createRuntime']>>['getDefinition']>
|
||||
result.server as ReturnType<
|
||||
Awaited<ReturnType<(typeof import('../runtime.js'))['createRuntime']>>['getDefinition']
|
||||
>
|
||||
),
|
||||
source: result.server.source,
|
||||
sources: options.includeSources ? result.server.sources : undefined,
|
||||
@ -193,7 +195,7 @@ export function createUnknownResult(server: ServerDefinition): ListSummaryResult
|
||||
}
|
||||
|
||||
export function buildAuthCommandHint(
|
||||
definition: ReturnType<Awaited<ReturnType<typeof import('../runtime.js')['createRuntime']>>['getDefinition']>
|
||||
definition: ReturnType<Awaited<ReturnType<(typeof import('../runtime.js'))['createRuntime']>>['getDefinition']>
|
||||
): string {
|
||||
if (definition.source?.kind === 'local' && definition.source.path === '<adhoc>') {
|
||||
if (definition.command.kind === 'http') {
|
||||
|
||||
@ -346,5 +346,5 @@ function normalizeLayers(
|
||||
): Array<{ path: string; mtimeMs: number | null }> {
|
||||
return layers
|
||||
.map((entry) => ({ path: path.resolve(entry.path), mtimeMs: entry.mtimeMs ?? null }))
|
||||
.sort((a, b) => a.path.localeCompare(b.path));
|
||||
.toSorted((a, b) => a.path.localeCompare(b.path));
|
||||
}
|
||||
|
||||
@ -68,7 +68,7 @@ export function resolveEnvPlaceholders(value: string): string {
|
||||
});
|
||||
|
||||
if (missing.size > 0) {
|
||||
const names = [...missing].sort().join(', ');
|
||||
const names = [...missing].toSorted().join(', ');
|
||||
throw new Error(`Environment variable(s) ${names} must be set for MCP header substitution.`);
|
||||
}
|
||||
|
||||
|
||||
@ -2,13 +2,7 @@ export type { CommandSpec, ServerDefinition } from './config.js';
|
||||
export { loadServerDefinitions } from './config.js';
|
||||
export type { CallResult, ConnectionIssue, ImageContent } from './result-utils.js';
|
||||
export { createCallResult, describeConnectionIssue, wrapCallResult } from './result-utils.js';
|
||||
export type {
|
||||
CallOptions,
|
||||
ListToolsOptions,
|
||||
Runtime,
|
||||
RuntimeLogger,
|
||||
ServerToolInfo,
|
||||
} from './runtime.js';
|
||||
export type { CallOptions, ListToolsOptions, Runtime, RuntimeLogger, ServerToolInfo } from './runtime.js';
|
||||
export { callOnce, createRuntime } from './runtime.js';
|
||||
export type { ServerProxyOptions } from './server-proxy.js';
|
||||
export { createServerProxy } from './server-proxy.js';
|
||||
|
||||
@ -15,7 +15,7 @@ export function materializeHeaders(
|
||||
resolved[key] = resolveEnvPlaceholders(value);
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
throw new Error(`Failed to resolve header '${key}' for server '${serverName}': ${message}`);
|
||||
throw new Error(`Failed to resolve header '${key}' for server '${serverName}': ${message}`, { cause: error });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -122,7 +122,7 @@ class McpRuntime implements Runtime {
|
||||
|
||||
// listServers returns configured names sorted alphabetically for stable CLI output.
|
||||
listServers(): string[] {
|
||||
return [...this.definitions.keys()].sort((a, b) => a.localeCompare(b));
|
||||
return [...this.definitions.keys()].toSorted((a, b) => a.localeCompare(b));
|
||||
}
|
||||
|
||||
// getDefinitions exposes raw server metadata to consumers such as the CLI.
|
||||
|
||||
@ -73,6 +73,8 @@ if (STDIO_TRACE_ENABLED) {
|
||||
console.log('[mcporter] STDIO trace logging enabled (set MCPORTER_STDIO_TRACE=0 to disable).');
|
||||
}
|
||||
|
||||
function ignoreEmitterError(): void {}
|
||||
|
||||
function destroyStream(stream: unknown): void {
|
||||
if (!stream || typeof stream !== 'object') {
|
||||
return;
|
||||
@ -85,9 +87,8 @@ function destroyStream(stream: unknown): void {
|
||||
end?: () => void;
|
||||
unref?: () => void;
|
||||
};
|
||||
const swallowError = () => {};
|
||||
try {
|
||||
emitter.on?.('error', swallowError);
|
||||
emitter.on?.('error', ignoreEmitterError);
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
@ -107,12 +108,12 @@ function destroyStream(stream: unknown): void {
|
||||
// ignore
|
||||
}
|
||||
try {
|
||||
emitter.off?.('error', swallowError);
|
||||
emitter.off?.('error', ignoreEmitterError);
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
try {
|
||||
emitter.removeListener?.('error', swallowError);
|
||||
emitter.removeListener?.('error', ignoreEmitterError);
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
@ -130,9 +131,8 @@ function waitForChildClose(child: MaybeChildProcess | undefined, timeoutMs: numb
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
let settled = false;
|
||||
const swallowProcessError = () => {};
|
||||
try {
|
||||
child.on?.('error', swallowProcessError);
|
||||
child.on?.('error', ignoreEmitterError);
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
@ -149,7 +149,7 @@ function waitForChildClose(child: MaybeChildProcess | undefined, timeoutMs: numb
|
||||
child.removeListener('close', finish);
|
||||
child.removeListener('error', finish);
|
||||
try {
|
||||
child.removeListener?.('error', swallowProcessError);
|
||||
child.removeListener?.('error', ignoreEmitterError);
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
@ -393,9 +393,8 @@ function patchStdioStart(): void {
|
||||
meta.stderrChunks.push(chunk.toString('utf8'));
|
||||
}
|
||||
};
|
||||
const swallowError = () => {};
|
||||
(targetStream as NodeJS.EventEmitter).on('data', handleChunk);
|
||||
(targetStream as NodeJS.EventEmitter).on('error', swallowError);
|
||||
(targetStream as NodeJS.EventEmitter).on('error', ignoreEmitterError);
|
||||
meta.listeners.push({
|
||||
stream: targetStream as NodeJS.EventEmitter & {
|
||||
removeListener?: (event: string, listener: (...args: unknown[]) => void) => void;
|
||||
@ -408,7 +407,7 @@ function patchStdioStart(): void {
|
||||
removeListener?: (event: string, listener: (...args: unknown[]) => void) => void;
|
||||
},
|
||||
event: 'error',
|
||||
handler: swallowError,
|
||||
handler: ignoreEmitterError,
|
||||
});
|
||||
}
|
||||
|
||||
@ -426,9 +425,8 @@ function patchStdioStart(): void {
|
||||
meta.stdoutChunks.push(chunk.toString('utf8'));
|
||||
}
|
||||
};
|
||||
const swallowStdoutError = () => {};
|
||||
stdoutStream.on('data', handleStdout);
|
||||
stdoutStream.on('error', swallowStdoutError);
|
||||
stdoutStream.on('error', ignoreEmitterError);
|
||||
meta.listeners.push({
|
||||
stream: stdoutStream,
|
||||
event: 'data',
|
||||
@ -437,7 +435,7 @@ function patchStdioStart(): void {
|
||||
meta.listeners.push({
|
||||
stream: stdoutStream,
|
||||
event: 'error',
|
||||
handler: swallowStdoutError,
|
||||
handler: ignoreEmitterError,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -281,11 +281,11 @@ export function createServerProxy(
|
||||
}
|
||||
|
||||
const base: ServerProxy = {
|
||||
call: async (toolName: string, options?: ToolCallOptions) => {
|
||||
const result = await runtime.callTool(serverName, toolName, options ?? {});
|
||||
call: async (toolName: string, callOptions?: ToolCallOptions) => {
|
||||
const result = await runtime.callTool(serverName, toolName, callOptions ?? {});
|
||||
return createCallResult(result);
|
||||
},
|
||||
listTools: (options) => runtime.listTools(serverName, options),
|
||||
listTools: (listOptions) => runtime.listTools(serverName, listOptions),
|
||||
};
|
||||
|
||||
return new Proxy(base as ServerProxy & Record<string | symbol, unknown>, {
|
||||
|
||||
@ -20,7 +20,7 @@ describe('handleAuth retry logic', () => {
|
||||
registerDefinition: vi.fn(),
|
||||
getDefinition: vi.fn().mockReturnValue(baseDefinition),
|
||||
listTools,
|
||||
} as unknown as Awaited<ReturnType<typeof import('../src/runtime.js')['createRuntime']>>;
|
||||
} as unknown as Awaited<ReturnType<(typeof import('../src/runtime.js'))['createRuntime']>>;
|
||||
|
||||
await expect(handleAuth(runtime, ['adhoc-server'])).resolves.toBeUndefined();
|
||||
expect(listTools).toHaveBeenCalledTimes(2);
|
||||
@ -33,7 +33,7 @@ describe('handleAuth retry logic', () => {
|
||||
registerDefinition: vi.fn(),
|
||||
getDefinition: vi.fn().mockReturnValue(baseDefinition),
|
||||
listTools,
|
||||
} as unknown as Awaited<ReturnType<typeof import('../src/runtime.js')['createRuntime']>>;
|
||||
} as unknown as Awaited<ReturnType<(typeof import('../src/runtime.js'))['createRuntime']>>;
|
||||
|
||||
await expect(handleAuth(runtime, ['adhoc-server'])).rejects.toThrow(/Failed to authorize/);
|
||||
expect(listTools).toHaveBeenCalledTimes(2);
|
||||
|
||||
@ -22,7 +22,7 @@ const createRuntimeDouble = () => {
|
||||
getDefinition,
|
||||
getDefinitions: () => Array.from(definitions.values()),
|
||||
listTools,
|
||||
} as unknown as Awaited<ReturnType<typeof import('../src/runtime.js')['createRuntime']>>;
|
||||
} as unknown as Awaited<ReturnType<(typeof import('../src/runtime.js'))['createRuntime']>>;
|
||||
return { runtime, listTools };
|
||||
};
|
||||
|
||||
@ -59,7 +59,7 @@ describe('mcporter auth ad-hoc support', () => {
|
||||
registerDefinition,
|
||||
listTools,
|
||||
getDefinition: () => definition,
|
||||
} as unknown as Awaited<ReturnType<typeof import('../src/runtime.js')['createRuntime']>>;
|
||||
} as unknown as Awaited<ReturnType<(typeof import('../src/runtime.js'))['createRuntime']>>;
|
||||
|
||||
await handleAuth(runtime, ['https://mcp.vercel.com']);
|
||||
|
||||
@ -78,7 +78,7 @@ describe('mcporter auth ad-hoc support', () => {
|
||||
registerDefinition: vi.fn(),
|
||||
listTools: vi.fn().mockRejectedValue(new Error('fetch failed: connect ECONNREFUSED 127.0.0.1:9000')),
|
||||
getDefinition: () => definition,
|
||||
} as unknown as Awaited<ReturnType<typeof import('../src/runtime.js')['createRuntime']>>;
|
||||
} as unknown as Awaited<ReturnType<(typeof import('../src/runtime.js'))['createRuntime']>>;
|
||||
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ describe('CLI call error reporting', () => {
|
||||
const runtime = {
|
||||
callTool,
|
||||
close: vi.fn().mockResolvedValue(undefined),
|
||||
} as unknown as Awaited<ReturnType<typeof import('../src/runtime.js')['createRuntime']>>;
|
||||
} as unknown as Awaited<ReturnType<(typeof import('../src/runtime.js'))['createRuntime']>>;
|
||||
|
||||
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
||||
@ -31,7 +31,7 @@ describe('CLI call error reporting', () => {
|
||||
const runtime = {
|
||||
callTool,
|
||||
close: vi.fn().mockResolvedValue(undefined),
|
||||
} as unknown as Awaited<ReturnType<typeof import('../src/runtime.js')['createRuntime']>>;
|
||||
} as unknown as Awaited<ReturnType<(typeof import('../src/runtime.js'))['createRuntime']>>;
|
||||
|
||||
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
@ -196,7 +196,7 @@ describe('CLI call execution behavior', () => {
|
||||
callTool,
|
||||
listTools,
|
||||
close: vi.fn().mockResolvedValue(undefined),
|
||||
} as unknown as Awaited<ReturnType<typeof import('../src/runtime.js')['createRuntime']>>;
|
||||
} as unknown as Awaited<ReturnType<(typeof import('../src/runtime.js'))['createRuntime']>>;
|
||||
|
||||
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
|
||||
@ -220,7 +220,7 @@ describe('CLI call execution behavior', () => {
|
||||
callTool,
|
||||
listTools,
|
||||
close: vi.fn().mockResolvedValue(undefined),
|
||||
} as unknown as Awaited<ReturnType<typeof import('../src/runtime.js')['createRuntime']>>;
|
||||
} as unknown as Awaited<ReturnType<(typeof import('../src/runtime.js'))['createRuntime']>>;
|
||||
|
||||
const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
@ -311,7 +311,7 @@ function createRuntimeStub(
|
||||
>,
|
||||
options: { definitions?: ServerDefinition[] } = {}
|
||||
): {
|
||||
runtime: Awaited<ReturnType<typeof import('../src/runtime.js')['createRuntime']>>;
|
||||
runtime: Awaited<ReturnType<(typeof import('../src/runtime.js'))['createRuntime']>>;
|
||||
callTool: ReturnType<typeof vi.fn>;
|
||||
listTools: ReturnType<typeof vi.fn>;
|
||||
} {
|
||||
@ -343,6 +343,6 @@ function createRuntimeStub(
|
||||
listTools,
|
||||
callTool,
|
||||
close,
|
||||
} as unknown as Awaited<ReturnType<typeof import('../src/runtime.js')['createRuntime']>>;
|
||||
} as unknown as Awaited<ReturnType<(typeof import('../src/runtime.js'))['createRuntime']>>;
|
||||
return { runtime, callTool, listTools };
|
||||
}
|
||||
|
||||
@ -659,12 +659,12 @@ await new Promise((resolve) => {
|
||||
expect(stats.isFile()).toBe(true);
|
||||
|
||||
const { stdout } = await new Promise<{ stdout: string; stderr: string }>((resolve, reject) => {
|
||||
execFile(binaryPath, [], { env: process.env }, (error, stdout, stderr) => {
|
||||
execFile(binaryPath, [], { env: process.env }, (error, childStdout, childStderr) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
resolve({ stdout, stderr });
|
||||
resolve({ stdout: childStdout, stderr: childStderr });
|
||||
});
|
||||
});
|
||||
expect(stdout).toContain('echo - Return the provided text');
|
||||
|
||||
@ -52,7 +52,7 @@ describe('CLI list classification and routing', () => {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
},
|
||||
} as unknown as Awaited<ReturnType<typeof import('../src/runtime.js')['createRuntime']>>;
|
||||
} as unknown as Awaited<ReturnType<(typeof import('../src/runtime.js'))['createRuntime']>>;
|
||||
|
||||
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
||||
@ -99,7 +99,7 @@ describe('CLI list classification and routing', () => {
|
||||
}),
|
||||
getDefinitions: () => Array.from(definitions.values()),
|
||||
listTools: vi.fn().mockRejectedValue(new Error('SSE error: Non-200 status code (401)')),
|
||||
} as unknown as Awaited<ReturnType<typeof import('../src/runtime.js')['createRuntime']>>;
|
||||
} as unknown as Awaited<ReturnType<(typeof import('../src/runtime.js'))['createRuntime']>>;
|
||||
|
||||
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
||||
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
@ -130,7 +130,7 @@ describe('CLI list classification and routing', () => {
|
||||
registerDefinition,
|
||||
getDefinition: () => definition,
|
||||
listTools,
|
||||
} as unknown as Awaited<ReturnType<typeof import('../src/runtime.js')['createRuntime']>>;
|
||||
} as unknown as Awaited<ReturnType<(typeof import('../src/runtime.js'))['createRuntime']>>;
|
||||
|
||||
await handleList(runtime, ['https://mcp.vercel.com']);
|
||||
|
||||
@ -153,7 +153,7 @@ describe('CLI list classification and routing', () => {
|
||||
registerDefinition,
|
||||
getDefinition: () => definition,
|
||||
listTools,
|
||||
} as unknown as Awaited<ReturnType<typeof import('../src/runtime.js')['createRuntime']>>;
|
||||
} as unknown as Awaited<ReturnType<(typeof import('../src/runtime.js'))['createRuntime']>>;
|
||||
|
||||
await handleList(runtime, ['https://www.shadcn.io/api/mcp.getComponents']);
|
||||
|
||||
@ -175,7 +175,7 @@ describe('CLI list classification and routing', () => {
|
||||
registerDefinition: vi.fn(),
|
||||
getDefinition: () => definition,
|
||||
listTools,
|
||||
} as unknown as Awaited<ReturnType<typeof import('../src/runtime.js')['createRuntime']>>;
|
||||
} as unknown as Awaited<ReturnType<(typeof import('../src/runtime.js'))['createRuntime']>>;
|
||||
|
||||
await handleList(runtime, ['shadcn.io/api/mcp.getComponents']);
|
||||
|
||||
@ -195,7 +195,7 @@ describe('CLI list classification and routing', () => {
|
||||
const runtime = {
|
||||
getDefinitions: () => [definition],
|
||||
listTools,
|
||||
} as unknown as Awaited<ReturnType<typeof import('../src/runtime.js')['createRuntime']>>;
|
||||
} as unknown as Awaited<ReturnType<(typeof import('../src/runtime.js'))['createRuntime']>>;
|
||||
|
||||
await handleList(runtime, []);
|
||||
|
||||
@ -223,7 +223,7 @@ describe('CLI list classification and routing', () => {
|
||||
},
|
||||
listTools,
|
||||
registerDefinition,
|
||||
} as unknown as Awaited<ReturnType<typeof import('../src/runtime.js')['createRuntime']>>;
|
||||
} as unknown as Awaited<ReturnType<(typeof import('../src/runtime.js'))['createRuntime']>>;
|
||||
|
||||
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
|
||||
@ -250,7 +250,7 @@ describe('CLI list classification and routing', () => {
|
||||
getDefinition,
|
||||
getDefinitions: () => [definition],
|
||||
listTools,
|
||||
} as unknown as Awaited<ReturnType<typeof import('../src/runtime.js')['createRuntime']>>;
|
||||
} as unknown as Awaited<ReturnType<(typeof import('../src/runtime.js'))['createRuntime']>>;
|
||||
|
||||
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
|
||||
@ -274,7 +274,7 @@ describe('CLI list classification and routing', () => {
|
||||
},
|
||||
getDefinitions: () => [definition],
|
||||
listTools,
|
||||
} as unknown as Awaited<ReturnType<typeof import('../src/runtime.js')['createRuntime']>>;
|
||||
} as unknown as Awaited<ReturnType<(typeof import('../src/runtime.js'))['createRuntime']>>;
|
||||
|
||||
const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
||||
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
|
||||
@ -66,7 +66,7 @@ describe('CLI list flag parsing', () => {
|
||||
new Promise((resolve) => {
|
||||
setTimeout(() => resolve([{ name: 'ok' }]), 50);
|
||||
}),
|
||||
} as unknown as Awaited<ReturnType<typeof import('../src/runtime.js')['createRuntime']>>;
|
||||
} as unknown as Awaited<ReturnType<(typeof import('../src/runtime.js'))['createRuntime']>>;
|
||||
|
||||
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
||||
|
||||
@ -41,7 +41,7 @@ describe('CLI list formatting', () => {
|
||||
command: { kind: 'http', url: new URL('https://example.com/mcp') },
|
||||
}),
|
||||
listTools: listToolsSpy,
|
||||
} as unknown as Awaited<ReturnType<typeof import('../src/runtime.js')['createRuntime']>>;
|
||||
} as unknown as Awaited<ReturnType<(typeof import('../src/runtime.js'))['createRuntime']>>;
|
||||
|
||||
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
|
||||
@ -94,7 +94,7 @@ describe('CLI list formatting', () => {
|
||||
}
|
||||
return Promise.reject(new Error('HTTP error 500: upstream unavailable'));
|
||||
},
|
||||
} as unknown as Awaited<ReturnType<typeof import('../src/runtime.js')['createRuntime']>>;
|
||||
} as unknown as Awaited<ReturnType<(typeof import('../src/runtime.js'))['createRuntime']>>;
|
||||
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
await handleList(runtime, ['--json']);
|
||||
const payload = JSON.parse(logSpy.mock.calls.at(-1)?.[0] ?? '{}');
|
||||
@ -133,7 +133,7 @@ describe('CLI list formatting', () => {
|
||||
getDefinitions: () => [definition],
|
||||
getDefinition: () => definition,
|
||||
registerDefinition: vi.fn(),
|
||||
} as unknown as Awaited<ReturnType<typeof import('../src/runtime.js')['createRuntime']>>;
|
||||
} as unknown as Awaited<ReturnType<(typeof import('../src/runtime.js'))['createRuntime']>>;
|
||||
|
||||
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
|
||||
@ -156,7 +156,7 @@ describe('CLI list formatting', () => {
|
||||
const runtime = {
|
||||
getDefinition: () => linearDefinition,
|
||||
listTools: listToolsSpy,
|
||||
} as unknown as Awaited<ReturnType<typeof import('../src/runtime.js')['createRuntime']>>;
|
||||
} as unknown as Awaited<ReturnType<(typeof import('../src/runtime.js'))['createRuntime']>>;
|
||||
|
||||
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
|
||||
@ -183,7 +183,7 @@ describe('CLI list formatting', () => {
|
||||
const runtime = {
|
||||
getDefinition: () => linearDefinition,
|
||||
listTools: listToolsSpy,
|
||||
} as unknown as Awaited<ReturnType<typeof import('../src/runtime.js')['createRuntime']>>;
|
||||
} as unknown as Awaited<ReturnType<(typeof import('../src/runtime.js'))['createRuntime']>>;
|
||||
|
||||
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
|
||||
@ -224,7 +224,7 @@ describe('CLI list formatting', () => {
|
||||
const runtime = {
|
||||
getDefinition: () => linearDefinition,
|
||||
listTools: listToolsSpy,
|
||||
} as unknown as Awaited<ReturnType<typeof import('../src/runtime.js')['createRuntime']>>;
|
||||
} as unknown as Awaited<ReturnType<(typeof import('../src/runtime.js'))['createRuntime']>>;
|
||||
|
||||
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
|
||||
@ -247,7 +247,7 @@ describe('CLI list formatting', () => {
|
||||
const runtime = {
|
||||
getDefinition: () => linearDefinition,
|
||||
listTools: listToolsSpy,
|
||||
} as unknown as Awaited<ReturnType<typeof import('../src/runtime.js')['createRuntime']>>;
|
||||
} as unknown as Awaited<ReturnType<(typeof import('../src/runtime.js'))['createRuntime']>>;
|
||||
|
||||
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
|
||||
@ -306,7 +306,7 @@ describe('CLI list formatting', () => {
|
||||
const runtime = {
|
||||
getDefinition: () => linearDefinition,
|
||||
listTools: listToolsSpy,
|
||||
} as unknown as Awaited<ReturnType<typeof import('../src/runtime.js')['createRuntime']>>;
|
||||
} as unknown as Awaited<ReturnType<(typeof import('../src/runtime.js'))['createRuntime']>>;
|
||||
|
||||
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
const nowSpy = vi.spyOn(Date, 'now').mockReturnValue(1_700_000_000_000);
|
||||
|
||||
@ -197,7 +197,7 @@ async function writeMetadataFixture(kind: ArtifactKind): Promise<string> {
|
||||
kind: 'http' as const,
|
||||
url: 'https://mcp.vercel.com',
|
||||
headers: {
|
||||
// biome-ignore lint/suspicious/noTemplateCurlyInString: metadata preserves env-placeholder format
|
||||
// Metadata preserves env-placeholder format.
|
||||
Authorization: 'Bearer ${VERCEL_TOKEN}',
|
||||
},
|
||||
},
|
||||
|
||||
@ -79,7 +79,7 @@ describe('config imports', () => {
|
||||
});
|
||||
const homeDir = ensureFakeHomeDir();
|
||||
|
||||
const names = servers.map((server) => server.name).sort();
|
||||
const names = servers.map((server) => server.name).toSorted();
|
||||
expect(names).toEqual([
|
||||
'claude-home',
|
||||
'claude-local',
|
||||
|
||||
@ -95,7 +95,7 @@ describe('loadServerDefinitions with layered configs', () => {
|
||||
);
|
||||
|
||||
const servers = await loadServerDefinitions({ rootDir: projectDir });
|
||||
const names = servers.map((server) => server.name).sort();
|
||||
const names = servers.map((server) => server.name).toSorted();
|
||||
expect(names).toEqual(['fromHome', 'fromProject', 'overrideMe']);
|
||||
|
||||
const merged = Object.fromEntries(servers.map((server) => [server.name, server]));
|
||||
|
||||
@ -271,9 +271,9 @@ describe('stdio transport environment', () => {
|
||||
cwd: '/repo',
|
||||
},
|
||||
env: {
|
||||
// biome-ignore lint/suspicious/noTemplateCurlyInString: placeholders resolve against process env at runtime
|
||||
// Placeholders resolve against process env at runtime.
|
||||
OBSIDIAN_API_KEY: '${OBSIDIAN_API_KEY}',
|
||||
// biome-ignore lint/suspicious/noTemplateCurlyInString: placeholders resolve against process env at runtime
|
||||
// Placeholders resolve against process env at runtime.
|
||||
OBSIDIAN_BASE_URL: '${OBSIDIAN_BASE_URL:-https://127.0.0.1:27124}',
|
||||
EMPTY_VAR: '',
|
||||
},
|
||||
|
||||
Loading…
Reference in New Issue
Block a user