fix: keep validator providers off root declarations (#2425)
Co-authored-by: Sehlani042 <257166922+Sehlani042@users.noreply.github.com>
This commit is contained in:
parent
d2f1bed893
commit
e8de519d31
6 changed files with 46 additions and 10 deletions
6
.changeset/silent-validators-wave.md
Normal file
6
.changeset/silent-validators-wave.md
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
'@modelcontextprotocol/client': patch
|
||||
'@modelcontextprotocol/server': patch
|
||||
---
|
||||
|
||||
Stop advertising validator provider classes from the root client/server type declarations. The provider classes remain available from the explicit validator subpaths.
|
||||
|
|
@ -12,6 +12,7 @@ const requireDist = createRequire(join(pkgDir, 'package.json'));
|
|||
const NODE_ONLY = /\b(child_process|cross-spawn|node:stream|node:child_process)\b/;
|
||||
// Anchored at start-of-line so JSDoc-example `from 'ajv'` strings in vendored chunks don't match.
|
||||
const VALIDATOR_BACKEND_IMPORT = /^import[^\n]*?from\s+["'](?:ajv|ajv-formats|@cfworker\/json-schema)["']/m;
|
||||
const ROOT_VALIDATOR_EXPORTS = ['AjvJsonSchemaValidator', 'CfWorkerJsonSchemaValidator', 'CfWorkerSchemaDraft'];
|
||||
|
||||
function chunkImportsOf(entryPath: string): string[] {
|
||||
const visited = new Set<string>();
|
||||
|
|
@ -29,6 +30,12 @@ function chunkImportsOf(entryPath: string): string[] {
|
|||
return [...visited];
|
||||
}
|
||||
|
||||
function rootExportBlockOf(content: string): string {
|
||||
const blocks = content.match(/(?:^|\n)export \{[\s\S]*?\};/g);
|
||||
expect(blocks).toBeTruthy();
|
||||
return blocks!.at(-1)!;
|
||||
}
|
||||
|
||||
describe('@modelcontextprotocol/client root entry is browser-safe', () => {
|
||||
beforeAll(() => {
|
||||
if (!existsSync(join(distDir, 'index.mjs')) || !existsSync(join(distDir, 'stdio.mjs'))) {
|
||||
|
|
@ -80,4 +87,13 @@ describe('@modelcontextprotocol/client root entry is browser-safe', () => {
|
|||
|
||||
expect(new AjvJsonSchemaValidator(ajv)).toBeInstanceOf(AjvJsonSchemaValidator);
|
||||
});
|
||||
|
||||
test('root declarations do not advertise validator provider classes', () => {
|
||||
for (const declaration of ['index.d.mts', 'index.d.cts']) {
|
||||
const rootExportBlock = rootExportBlockOf(readFileSync(join(distDir, declaration), 'utf8'));
|
||||
for (const symbol of ROOT_VALIDATOR_EXPORTS) {
|
||||
expect(rootExportBlock).not.toMatch(new RegExp(`\\b(?:type\\s+)?${symbol}\\b`));
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -131,10 +131,9 @@ export {
|
|||
export type { SpecTypeName, SpecTypes } from '../../types/specTypeSchema';
|
||||
export { isSpecType, specTypeSchemas } from '../../types/specTypeSchema';
|
||||
export type { StandardSchemaV1, StandardSchemaV1Sync, StandardSchemaWithJSON } from '../../util/standardSchema';
|
||||
// Validator providers are type-only here — import the runtime classes from the explicit
|
||||
// `@modelcontextprotocol/{client,server}/validators/{ajv,cf-worker}` subpaths to customise.
|
||||
export type { AjvJsonSchemaValidator } from '../../validators/ajvProvider';
|
||||
export type { CfWorkerJsonSchemaValidator, CfWorkerSchemaDraft } from '../../validators/cfWorkerProvider';
|
||||
// Validator provider classes stay subpath-only. Re-exporting them here, even as
|
||||
// `type`, can make generated root declarations advertise runtime-shaped root
|
||||
// exports that the package root does not provide.
|
||||
// fromJsonSchema is intentionally NOT exported here — the server and client packages
|
||||
// provide runtime-aware wrappers that default to the appropriate validator via _shims.
|
||||
export type { JsonSchemaType, JsonSchemaValidator, jsonSchemaValidator, JsonSchemaValidatorResult } from '../../validators/types';
|
||||
|
|
|
|||
|
|
@ -33,9 +33,8 @@ export * from './util/standardSchema';
|
|||
export * from './util/zodCompat';
|
||||
export { codecForVersion, MODERN_WIRE_REVISION } from './wire/codec';
|
||||
|
||||
// Validator providers are type-only here — import the runtime classes from the explicit
|
||||
// `@modelcontextprotocol/{client,server}/validators/{ajv,cf-worker}` subpaths to customise.
|
||||
export type { AjvJsonSchemaValidator } from './validators/ajvProvider';
|
||||
export type { CfWorkerJsonSchemaValidator, CfWorkerSchemaDraft } from './validators/cfWorkerProvider';
|
||||
// Validator provider classes stay subpath-only. Re-exporting them here, even as
|
||||
// `type`, can make generated client/server root declarations advertise
|
||||
// runtime-shaped root exports that the package root does not provide.
|
||||
export * from './validators/fromJsonSchema';
|
||||
export type { JsonSchemaType, JsonSchemaValidator, jsonSchemaValidator, JsonSchemaValidatorResult } from './validators/types';
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ const requireDist = createRequire(join(pkgDir, 'package.json'));
|
|||
const NODE_ONLY = /\b(child_process|cross-spawn|node:stream|node:child_process)\b/;
|
||||
// Anchored at start-of-line so JSDoc-example `from 'ajv'` strings in vendored chunks don't match.
|
||||
const VALIDATOR_BACKEND_IMPORT = /^import[^\n]*?from\s+["'](?:ajv|ajv-formats|@cfworker\/json-schema)["']/m;
|
||||
const ROOT_VALIDATOR_EXPORTS = ['AjvJsonSchemaValidator', 'CfWorkerJsonSchemaValidator', 'CfWorkerSchemaDraft'];
|
||||
|
||||
function chunkImportsOf(entryPath: string): string[] {
|
||||
const visited = new Set<string>();
|
||||
|
|
@ -29,6 +30,12 @@ function chunkImportsOf(entryPath: string): string[] {
|
|||
return [...visited];
|
||||
}
|
||||
|
||||
function rootExportBlockOf(content: string): string {
|
||||
const blocks = content.match(/(?:^|\n)export \{[\s\S]*?\};/g);
|
||||
expect(blocks).toBeTruthy();
|
||||
return blocks!.at(-1)!;
|
||||
}
|
||||
|
||||
describe('@modelcontextprotocol/server root entry is browser-safe', () => {
|
||||
beforeAll(() => {
|
||||
if (!existsSync(join(distDir, 'index.mjs')) || !existsSync(join(distDir, 'stdio.mjs'))) {
|
||||
|
|
@ -81,4 +88,13 @@ describe('@modelcontextprotocol/server root entry is browser-safe', () => {
|
|||
|
||||
expect(new AjvJsonSchemaValidator(ajv)).toBeInstanceOf(AjvJsonSchemaValidator);
|
||||
});
|
||||
|
||||
test('root declarations do not advertise validator provider classes', () => {
|
||||
for (const declaration of ['index.d.mts', 'index.d.cts']) {
|
||||
const rootExportBlock = rootExportBlockOf(readFileSync(join(distDir, declaration), 'utf8'));
|
||||
for (const symbol of ROOT_VALIDATOR_EXPORTS) {
|
||||
expect(rootExportBlock).not.toMatch(new RegExp(`\\b(?:type\\s+)?${symbol}\\b`));
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ try {
|
|||
path.join(dir, 'consumer.ts'),
|
||||
[
|
||||
"import { Client } from '@modelcontextprotocol/client';",
|
||||
"import type { AjvJsonSchemaValidator as ClientAjv } from '@modelcontextprotocol/client';",
|
||||
"import type { JsonSchemaType as ClientSchema } from '@modelcontextprotocol/client';",
|
||||
"import { AjvJsonSchemaValidator } from '@modelcontextprotocol/client/validators/ajv';",
|
||||
"import { CfWorkerJsonSchemaValidator as ClientCf } from '@modelcontextprotocol/client/validators/cf-worker';",
|
||||
"import { StdioClientTransport } from '@modelcontextprotocol/client/stdio';",
|
||||
|
|
@ -24,7 +24,7 @@ try {
|
|||
"import { StdioServerTransport } from '@modelcontextprotocol/server/stdio';",
|
||||
"export const c = new Client({ name: 'smoke', version: '1.0.0' });",
|
||||
"export const s = new McpServer({ name: 'smoke', version: '1.0.0' });",
|
||||
'export type T = ClientAjv;',
|
||||
'export type T = ClientSchema;',
|
||||
'export { AjvJsonSchemaValidator, ServerAjv, ClientCf, ServerCf, StdioClientTransport, StdioServerTransport };',
|
||||
''
|
||||
].join('\n')
|
||||
|
|
|
|||
Loading…
Reference in a new issue