adjust prettier to use more defaults (#8)
* simplify prettier to use more defaults * apply new prettier
This commit is contained in:
parent
05df535e40
commit
b377251b15
33 changed files with 12352 additions and 12153 deletions
|
|
@ -1,14 +1,6 @@
|
|||
{
|
||||
"printWidth": 140,
|
||||
"tabWidth": 4,
|
||||
"useTabs": false,
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"bracketSpacing": true,
|
||||
"bracketSameLine": false,
|
||||
"proseWrap": "always",
|
||||
"arrowParens": "avoid",
|
||||
"overrides": [
|
||||
{
|
||||
"files": "**/*.md",
|
||||
|
|
|
|||
|
|
@ -12,7 +12,10 @@ export default tseslint.config(
|
|||
reportUnusedDisableDirectives: false
|
||||
},
|
||||
rules: {
|
||||
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
'error',
|
||||
{ argsIgnorePattern: '^_' }
|
||||
],
|
||||
'@typescript-eslint/no-explicit-any': 'off'
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ async function main(): Promise<void> {
|
|||
}
|
||||
}
|
||||
|
||||
main().catch(error => {
|
||||
main().catch((error) => {
|
||||
console.error('Unhandled error:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ async function main(): Promise<void> {
|
|||
}
|
||||
}
|
||||
|
||||
main().catch(error => {
|
||||
main().catch((error) => {
|
||||
console.error('Unhandled error:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ async function main(): Promise<void> {
|
|||
}
|
||||
}
|
||||
|
||||
main().catch(error => {
|
||||
main().catch((error) => {
|
||||
console.error('Unhandled error:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -8,7 +8,10 @@
|
|||
* we use tool() instead of registerTool() as there is a bug with logging in registerTool().
|
||||
*/
|
||||
|
||||
import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
|
||||
import {
|
||||
McpServer,
|
||||
ResourceTemplate
|
||||
} from '@modelcontextprotocol/sdk/server/mcp.js';
|
||||
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
||||
import { z } from 'zod';
|
||||
import express from 'express';
|
||||
|
|
@ -24,10 +27,12 @@ const transports: { [sessionId: string]: StreamableHTTPServerTransport } = {};
|
|||
const servers: { [sessionId: string]: McpServer } = {};
|
||||
|
||||
// Sample base64 encoded 1x1 red PNG pixel for testing
|
||||
const TEST_IMAGE_BASE64 = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==';
|
||||
const TEST_IMAGE_BASE64 =
|
||||
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFBQIAX8jx0gAAAABJRU5ErkJggg==';
|
||||
|
||||
// Sample base64 encoded minimal WAV file for testing
|
||||
const TEST_AUDIO_BASE64 = 'UklGRiYAAABXQVZFZm10IBAAAAABAAEAQB8AAAB9AAACABAAZGF0YQIAAAA=';
|
||||
const TEST_AUDIO_BASE64 =
|
||||
'UklGRiYAAABXQVZFZm10IBAAAAABAAEAQB8AAAB9AAACABAAZGF0YQIAAAA=';
|
||||
|
||||
// Function to create a new MCP server instance (one per session)
|
||||
function createMcpServer() {
|
||||
|
|
@ -56,7 +61,15 @@ function createMcpServer() {
|
|||
|
||||
// Helper to send log messages using the underlying server
|
||||
function sendLog(
|
||||
level: 'debug' | 'info' | 'notice' | 'warning' | 'error' | 'critical' | 'alert' | 'emergency',
|
||||
level:
|
||||
| 'debug'
|
||||
| 'info'
|
||||
| 'notice'
|
||||
| 'warning'
|
||||
| 'error'
|
||||
| 'critical'
|
||||
| 'alert'
|
||||
| 'emergency',
|
||||
message: string,
|
||||
data?: any
|
||||
) {
|
||||
|
|
@ -77,11 +90,18 @@ function createMcpServer() {
|
|||
// ===== TOOLS =====
|
||||
|
||||
// Simple text tool
|
||||
mcpServer.tool('test_simple_text', 'Tests simple text content response', {}, async () => {
|
||||
mcpServer.tool(
|
||||
'test_simple_text',
|
||||
'Tests simple text content response',
|
||||
{},
|
||||
async () => {
|
||||
return {
|
||||
content: [{ type: 'text', text: 'This is a simple text response for testing.' }]
|
||||
content: [
|
||||
{ type: 'text', text: 'This is a simple text response for testing.' }
|
||||
]
|
||||
};
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// Image content tool
|
||||
mcpServer.registerTool(
|
||||
|
|
@ -91,7 +111,9 @@ function createMcpServer() {
|
|||
},
|
||||
async () => {
|
||||
return {
|
||||
content: [{ type: 'image', data: TEST_IMAGE_BASE64, mimeType: 'image/png' }]
|
||||
content: [
|
||||
{ type: 'image', data: TEST_IMAGE_BASE64, mimeType: 'image/png' }
|
||||
]
|
||||
};
|
||||
}
|
||||
);
|
||||
|
|
@ -104,7 +126,9 @@ function createMcpServer() {
|
|||
},
|
||||
async () => {
|
||||
return {
|
||||
content: [{ type: 'audio', data: TEST_AUDIO_BASE64, mimeType: 'audio/wav' }]
|
||||
content: [
|
||||
{ type: 'audio', data: TEST_AUDIO_BASE64, mimeType: 'audio/wav' }
|
||||
]
|
||||
};
|
||||
}
|
||||
);
|
||||
|
|
@ -135,7 +159,8 @@ function createMcpServer() {
|
|||
mcpServer.registerTool(
|
||||
'test_multiple_content_types',
|
||||
{
|
||||
description: 'Tests response with multiple content types (text, image, resource)'
|
||||
description:
|
||||
'Tests response with multiple content types (text, image, resource)'
|
||||
},
|
||||
async () => {
|
||||
return {
|
||||
|
|
@ -170,7 +195,7 @@ function createMcpServer() {
|
|||
data: 'Tool execution started'
|
||||
}
|
||||
});
|
||||
await new Promise(resolve => setTimeout(resolve, 50));
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
|
||||
await sendNotification({
|
||||
method: 'notifications/message',
|
||||
|
|
@ -179,7 +204,7 @@ function createMcpServer() {
|
|||
data: 'Tool processing data'
|
||||
}
|
||||
});
|
||||
await new Promise(resolve => setTimeout(resolve, 50));
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
|
||||
await sendNotification({
|
||||
method: 'notifications/message',
|
||||
|
|
@ -189,7 +214,9 @@ function createMcpServer() {
|
|||
}
|
||||
});
|
||||
return {
|
||||
content: [{ type: 'text', text: 'Tool with logging executed successfully' }]
|
||||
content: [
|
||||
{ type: 'text', text: 'Tool with logging executed successfully' }
|
||||
]
|
||||
};
|
||||
}
|
||||
);
|
||||
|
|
@ -213,7 +240,7 @@ function createMcpServer() {
|
|||
message: `Completed step ${0} of ${100}`
|
||||
}
|
||||
});
|
||||
await new Promise(resolve => setTimeout(resolve, 50));
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
|
||||
await sendNotification({
|
||||
method: 'notifications/progress',
|
||||
|
|
@ -224,7 +251,7 @@ function createMcpServer() {
|
|||
message: `Completed step ${50} of ${100}`
|
||||
}
|
||||
});
|
||||
await new Promise(resolve => setTimeout(resolve, 50));
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
|
||||
await sendNotification({
|
||||
method: 'notifications/progress',
|
||||
|
|
@ -281,11 +308,16 @@ function createMcpServer() {
|
|||
maxTokens: 100
|
||||
}
|
||||
},
|
||||
z.object({ method: z.literal('sampling/createMessage') }).passthrough() as any
|
||||
z
|
||||
.object({ method: z.literal('sampling/createMessage') })
|
||||
.passthrough() as any
|
||||
);
|
||||
|
||||
const samplingResult = result as any;
|
||||
const modelResponse = samplingResult.content?.text || samplingResult.message?.content?.text || 'No response';
|
||||
const modelResponse =
|
||||
samplingResult.content?.text ||
|
||||
samplingResult.message?.content?.text ||
|
||||
'No response';
|
||||
|
||||
return {
|
||||
content: [
|
||||
|
|
@ -337,7 +369,9 @@ function createMcpServer() {
|
|||
}
|
||||
}
|
||||
},
|
||||
z.object({ method: z.literal('elicitation/create') }).passthrough() as any
|
||||
z
|
||||
.object({ method: z.literal('elicitation/create') })
|
||||
.passthrough() as any
|
||||
);
|
||||
|
||||
const elicitResult = result as any;
|
||||
|
|
@ -462,19 +496,25 @@ function createMcpServer() {
|
|||
);
|
||||
|
||||
// Subscribe/Unsubscribe handlers
|
||||
mcpServer.server.setRequestHandler(z.object({ method: z.literal('resources/subscribe') }).passthrough(), async (request: any) => {
|
||||
mcpServer.server.setRequestHandler(
|
||||
z.object({ method: z.literal('resources/subscribe') }).passthrough(),
|
||||
async (request: any) => {
|
||||
const uri = request.params.uri;
|
||||
resourceSubscriptions.add(uri);
|
||||
sendLog('info', `Subscribed to resource: ${uri}`);
|
||||
return {};
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
mcpServer.server.setRequestHandler(z.object({ method: z.literal('resources/unsubscribe') }).passthrough(), async (request: any) => {
|
||||
mcpServer.server.setRequestHandler(
|
||||
z.object({ method: z.literal('resources/unsubscribe') }).passthrough(),
|
||||
async (request: any) => {
|
||||
const uri = request.params.uri;
|
||||
resourceSubscriptions.delete(uri);
|
||||
sendLog('info', `Unsubscribed from resource: ${uri}`);
|
||||
return {};
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// ===== PROMPTS =====
|
||||
|
||||
|
|
@ -490,7 +530,10 @@ function createMcpServer() {
|
|||
messages: [
|
||||
{
|
||||
role: 'user',
|
||||
content: { type: 'text', text: 'This is a simple prompt for testing.' }
|
||||
content: {
|
||||
type: 'text',
|
||||
text: 'This is a simple prompt for testing.'
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
|
@ -508,7 +551,7 @@ function createMcpServer() {
|
|||
arg2: z.string().describe('Second test argument')
|
||||
}
|
||||
},
|
||||
async args => {
|
||||
async (args) => {
|
||||
const { arg1, arg2 } = args;
|
||||
return {
|
||||
messages: [
|
||||
|
|
@ -534,7 +577,7 @@ function createMcpServer() {
|
|||
resourceUri: z.string().describe('URI of the resource to embed')
|
||||
}
|
||||
},
|
||||
async args => {
|
||||
async (args) => {
|
||||
const uri = args.resourceUri;
|
||||
return {
|
||||
messages: [
|
||||
|
|
@ -551,7 +594,10 @@ function createMcpServer() {
|
|||
},
|
||||
{
|
||||
role: 'user',
|
||||
content: { type: 'text', text: 'Please process the embedded resource above.' }
|
||||
content: {
|
||||
type: 'text',
|
||||
text: 'Please process the embedded resource above.'
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
|
@ -570,7 +616,11 @@ function createMcpServer() {
|
|||
messages: [
|
||||
{
|
||||
role: 'user',
|
||||
content: { type: 'image', data: TEST_IMAGE_BASE64, mimeType: 'image/png' }
|
||||
content: {
|
||||
type: 'image',
|
||||
data: TEST_IMAGE_BASE64,
|
||||
mimeType: 'image/png'
|
||||
}
|
||||
},
|
||||
{
|
||||
role: 'user',
|
||||
|
|
@ -583,15 +633,20 @@ function createMcpServer() {
|
|||
|
||||
// ===== LOGGING =====
|
||||
|
||||
mcpServer.server.setRequestHandler(z.object({ method: z.literal('logging/setLevel') }).passthrough(), async (request: any) => {
|
||||
mcpServer.server.setRequestHandler(
|
||||
z.object({ method: z.literal('logging/setLevel') }).passthrough(),
|
||||
async (request: any) => {
|
||||
const level = request.params.level;
|
||||
sendLog('info', `Log level set to: ${level}`);
|
||||
return {};
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// ===== COMPLETION =====
|
||||
|
||||
mcpServer.server.setRequestHandler(z.object({ method: z.literal('completion/complete') }).passthrough(), async (_request: any) => {
|
||||
mcpServer.server.setRequestHandler(
|
||||
z.object({ method: z.literal('completion/complete') }).passthrough(),
|
||||
async (_request: any) => {
|
||||
// Basic completion support - returns empty array for conformance
|
||||
// Real implementations would provide contextual suggestions
|
||||
return {
|
||||
|
|
@ -601,7 +656,8 @@ function createMcpServer() {
|
|||
hasMore: false
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
return mcpServer;
|
||||
}
|
||||
|
|
@ -641,7 +697,7 @@ app.post('/mcp', async (req, res) => {
|
|||
|
||||
transport = new StreamableHTTPServerTransport({
|
||||
sessionIdGenerator: () => randomUUID(),
|
||||
onsessioninitialized: newSessionId => {
|
||||
onsessioninitialized: (newSessionId) => {
|
||||
transports[newSessionId] = transport;
|
||||
servers[newSessionId] = mcpServer;
|
||||
console.log(`Session initialized with ID: ${newSessionId}`);
|
||||
|
|
@ -743,6 +799,8 @@ app.delete('/mcp', async (req, res) => {
|
|||
// Start server
|
||||
const PORT = process.env.PORT || 3000;
|
||||
app.listen(PORT, () => {
|
||||
console.log(`MCP Conformance Test Server running on http://localhost:${PORT}`);
|
||||
console.log(
|
||||
`MCP Conformance Test Server running on http://localhost:${PORT}`
|
||||
);
|
||||
console.log(` - MCP endpoint: http://localhost:${PORT}/mcp`);
|
||||
});
|
||||
|
|
|
|||
1
package-lock.json
generated
1
package-lock.json
generated
|
|
@ -59,6 +59,7 @@
|
|||
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.27.1",
|
||||
"@babel/generator": "^7.28.5",
|
||||
|
|
|
|||
|
|
@ -1,13 +1,21 @@
|
|||
import { ConformanceCheck, CheckStatus } from '../types.js';
|
||||
|
||||
export function createServerInfoCheck(serverInfo: { name: string; version: string }): ConformanceCheck {
|
||||
export function createServerInfoCheck(serverInfo: {
|
||||
name: string;
|
||||
version: string;
|
||||
}): ConformanceCheck {
|
||||
return {
|
||||
id: 'server-info',
|
||||
name: 'ServerInfo',
|
||||
description: 'Test server info returned to client',
|
||||
status: 'INFO',
|
||||
timestamp: new Date().toISOString(),
|
||||
specReferences: [{ id: 'MCP-Lifecycle', url: 'https://modelcontextprotocol.io/specification/2025-06-18/basic/lifecycle' }],
|
||||
specReferences: [
|
||||
{
|
||||
id: 'MCP-Lifecycle',
|
||||
url: 'https://modelcontextprotocol.io/specification/2025-06-18/basic/lifecycle'
|
||||
}
|
||||
],
|
||||
details: {
|
||||
serverName: serverInfo.name,
|
||||
serverVersion: serverInfo.version
|
||||
|
|
@ -15,15 +23,22 @@ export function createServerInfoCheck(serverInfo: { name: string; version: strin
|
|||
};
|
||||
}
|
||||
|
||||
export function createClientInitializationCheck(initializeRequest: any, expectedSpecVersion: string = '2025-06-18'): ConformanceCheck {
|
||||
export function createClientInitializationCheck(
|
||||
initializeRequest: any,
|
||||
expectedSpecVersion: string = '2025-06-18'
|
||||
): ConformanceCheck {
|
||||
const protocolVersionSent = initializeRequest?.protocolVersion;
|
||||
const versionMatch = protocolVersionSent === expectedSpecVersion;
|
||||
|
||||
const errors: string[] = [];
|
||||
if (!protocolVersionSent) errors.push('Protocol version not provided');
|
||||
if (!versionMatch) errors.push(`Version mismatch: expected ${expectedSpecVersion}, got ${protocolVersionSent}`);
|
||||
if (!versionMatch)
|
||||
errors.push(
|
||||
`Version mismatch: expected ${expectedSpecVersion}, got ${protocolVersionSent}`
|
||||
);
|
||||
if (!initializeRequest?.clientInfo?.name) errors.push('Client name missing');
|
||||
if (!initializeRequest?.clientInfo?.version) errors.push('Client version missing');
|
||||
if (!initializeRequest?.clientInfo?.version)
|
||||
errors.push('Client version missing');
|
||||
|
||||
const status: CheckStatus = errors.length === 0 ? 'SUCCESS' : 'FAILURE';
|
||||
|
||||
|
|
@ -33,7 +48,12 @@ export function createClientInitializationCheck(initializeRequest: any, expected
|
|||
description: 'Validates that MCP client properly initializes with server',
|
||||
status,
|
||||
timestamp: new Date().toISOString(),
|
||||
specReferences: [{ id: 'MCP-Lifecycle', url: 'https://modelcontextprotocol.io/specification/2025-06-18/basic/lifecycle' }],
|
||||
specReferences: [
|
||||
{
|
||||
id: 'MCP-Lifecycle',
|
||||
url: 'https://modelcontextprotocol.io/specification/2025-06-18/basic/lifecycle'
|
||||
}
|
||||
],
|
||||
details: {
|
||||
protocolVersionSent,
|
||||
expectedSpecVersion,
|
||||
|
|
|
|||
|
|
@ -22,7 +22,11 @@ function createResultDir(scenario: string): string {
|
|||
return path.join('results', `${scenario}-${timestamp}`);
|
||||
}
|
||||
|
||||
async function executeClient(command: string, serverUrl: string, timeout: number = 30000): Promise<ClientExecutionResult> {
|
||||
async function executeClient(
|
||||
command: string,
|
||||
serverUrl: string,
|
||||
timeout: number = 30000
|
||||
): Promise<ClientExecutionResult> {
|
||||
const commandParts = command.split(' ');
|
||||
const executable = commandParts[0];
|
||||
const args = [...commandParts.slice(1), serverUrl];
|
||||
|
|
@ -31,7 +35,7 @@ async function executeClient(command: string, serverUrl: string, timeout: number
|
|||
let stderr = '';
|
||||
let timedOut = false;
|
||||
|
||||
return new Promise(resolve => {
|
||||
return new Promise((resolve) => {
|
||||
const process = spawn(executable, args, {
|
||||
shell: true,
|
||||
stdio: 'pipe'
|
||||
|
|
@ -43,18 +47,18 @@ async function executeClient(command: string, serverUrl: string, timeout: number
|
|||
}, timeout);
|
||||
|
||||
if (process.stdout) {
|
||||
process.stdout.on('data', data => {
|
||||
process.stdout.on('data', (data) => {
|
||||
stdout += data.toString();
|
||||
});
|
||||
}
|
||||
|
||||
if (process.stderr) {
|
||||
process.stderr.on('data', data => {
|
||||
process.stderr.on('data', (data) => {
|
||||
stderr += data.toString();
|
||||
});
|
||||
}
|
||||
|
||||
process.on('close', code => {
|
||||
process.on('close', (code) => {
|
||||
clearTimeout(timeoutHandle);
|
||||
resolve({
|
||||
exitCode: code || 0,
|
||||
|
|
@ -64,7 +68,7 @@ async function executeClient(command: string, serverUrl: string, timeout: number
|
|||
});
|
||||
});
|
||||
|
||||
process.on('error', error => {
|
||||
process.on('error', (error) => {
|
||||
clearTimeout(timeoutHandle);
|
||||
resolve({
|
||||
exitCode: -1,
|
||||
|
|
@ -100,11 +104,18 @@ export async function runConformanceTest(
|
|||
console.log(`Executing client: ${clientCommand} ${urls.serverUrl}`);
|
||||
|
||||
try {
|
||||
const clientOutput = await executeClient(clientCommand, urls.serverUrl, timeout);
|
||||
const clientOutput = await executeClient(
|
||||
clientCommand,
|
||||
urls.serverUrl,
|
||||
timeout
|
||||
);
|
||||
|
||||
const checks = scenario.getChecks();
|
||||
|
||||
await fs.writeFile(path.join(resultDir, 'checks.json'), JSON.stringify(checks, null, 2));
|
||||
await fs.writeFile(
|
||||
path.join(resultDir, 'checks.json'),
|
||||
JSON.stringify(checks, null, 2)
|
||||
);
|
||||
|
||||
await fs.writeFile(path.join(resultDir, 'stdout.txt'), clientOutput.stdout);
|
||||
|
||||
|
|
@ -142,7 +153,10 @@ async function runInteractiveMode(scenarioName: string): Promise<void> {
|
|||
console.log('\nShutting down...');
|
||||
|
||||
const checks = scenario.getChecks();
|
||||
await fs.writeFile(path.join(resultDir, 'checks.json'), JSON.stringify(checks, null, 2));
|
||||
await fs.writeFile(
|
||||
path.join(resultDir, 'checks.json'),
|
||||
JSON.stringify(checks, null, 2)
|
||||
);
|
||||
|
||||
console.log(`\nChecks:\n${JSON.stringify(checks, null, 2)}`);
|
||||
console.log(`\nChecks saved to ${resultDir}/checks.json`);
|
||||
|
|
@ -173,8 +187,12 @@ async function main(): Promise<void> {
|
|||
}
|
||||
|
||||
if (!scenario) {
|
||||
console.error('Usage: runner --scenario <scenario> [--command "<command>"]');
|
||||
console.error('Example: runner --scenario initialize --command "tsx examples/clients/typescript/test1.ts"');
|
||||
console.error(
|
||||
'Usage: runner --scenario <scenario> [--command "<command>"]'
|
||||
);
|
||||
console.error(
|
||||
'Example: runner --scenario initialize --command "tsx examples/clients/typescript/test1.ts"'
|
||||
);
|
||||
console.error('Or run without --command for interactive mode');
|
||||
process.exit(1);
|
||||
}
|
||||
|
|
@ -192,9 +210,11 @@ async function main(): Promise<void> {
|
|||
try {
|
||||
const result = await runConformanceTest(command, scenario);
|
||||
|
||||
const denominator = result.checks.filter(c => c.status === 'SUCCESS' || c.status == 'FAILURE').length;
|
||||
const passed = result.checks.filter(c => c.status === 'SUCCESS').length;
|
||||
const failed = result.checks.filter(c => c.status === 'FAILURE').length;
|
||||
const denominator = result.checks.filter(
|
||||
(c) => c.status === 'SUCCESS' || c.status == 'FAILURE'
|
||||
).length;
|
||||
const passed = result.checks.filter((c) => c.status === 'SUCCESS').length;
|
||||
const failed = result.checks.filter((c) => c.status === 'FAILURE').length;
|
||||
|
||||
console.log(`Checks:\n${JSON.stringify(result.checks, null, 2)}`);
|
||||
|
||||
|
|
@ -204,8 +224,8 @@ async function main(): Promise<void> {
|
|||
if (failed > 0) {
|
||||
console.log('\nFailed Checks:');
|
||||
result.checks
|
||||
.filter(c => c.status === 'FAILURE')
|
||||
.forEach(c => {
|
||||
.filter((c) => c.status === 'FAILURE')
|
||||
.forEach((c) => {
|
||||
console.log(` - ${c.name}: ${c.description}`);
|
||||
if (c.errorMessage) {
|
||||
console.log(` Error: ${c.errorMessage}`);
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue