项目文件夹

文件
zyzyzyryxy 94752ffade fix: prevent dropping license notices on some files when publishing (#604)
This PR prevents license notices being dropped when creating package for
publication.

This can happen when first import in the file is type-only import that
gets removed during build. When there is no empty line between the
license block comment and such import, the comment is treated as related
to the import and gets removed alongside it.
Adding an empty line between copyright notice and the import fixes the
issue.

Co-authored-by: Piotr Paulski <piotrpaulski@chromium.org>
2025-11-24 12:38:30 +00:00

104 行
2.6 KiB
TypeScript

/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import assert from 'node:assert';
import fs from 'node:fs';
import {describe, it} from 'node:test';
import {Client} from '@modelcontextprotocol/sdk/client/index.js';
import {StdioClientTransport} from '@modelcontextprotocol/sdk/client/stdio.js';
import {executablePath} from 'puppeteer';
describe('e2e', () => {
async function withClient(cb: (client: Client) => Promise<void>) {
const transport = new StdioClientTransport({
command: 'node',
args: [
'build/src/index.js',
'--headless',
'--isolated',
'--executable-path',
executablePath(),
],
});
const client = new Client(
{
name: 'e2e-test',
version: '1.0.0',
},
{
capabilities: {},
},
);
try {
await client.connect(transport);
await cb(client);
} finally {
await client.close();
}
}
it('calls a tool', async () => {
await withClient(async client => {
const result = await client.callTool({
name: 'list_pages',
arguments: {},
});
assert.deepStrictEqual(result, {
content: [
{
type: 'text',
text: '# list_pages response\n## Pages\n0: about:blank [selected]',
},
],
});
});
});
it('calls a tool multiple times', async () => {
await withClient(async client => {
let result = await client.callTool({
name: 'list_pages',
arguments: {},
});
result = await client.callTool({
name: 'list_pages',
arguments: {},
});
assert.deepStrictEqual(result, {
content: [
{
type: 'text',
text: '# list_pages response\n## Pages\n0: about:blank [selected]',
},
],
});
});
});
it('has all tools', async () => {
await withClient(async client => {
const {tools} = await client.listTools();
const exposedNames = tools.map(t => t.name).sort();
const files = fs.readdirSync('build/src/tools');
const definedNames = [];
for (const file of files) {
if (file === 'ToolDefinition.js') {
continue;
}
const fileTools = await import(`../src/tools/${file}`);
for (const maybeTool of Object.values<object>(fileTools)) {
if ('name' in maybeTool) {
definedNames.push(maybeTool.name);
}
}
}
definedNames.sort();
assert.deepStrictEqual(exposedNames, definedNames);
});
});
});