Skip to content

Commit 5820d9a

Browse files
committed
fix: keep validator providers off root declarations
1 parent 7635115 commit 5820d9a

4 files changed

Lines changed: 38 additions & 8 deletions

File tree

packages/client/test/client/barrelClean.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const distDir = join(pkgDir, 'dist');
1010
const NODE_ONLY = /\b(child_process|cross-spawn|node:stream|node:child_process)\b/;
1111
// Anchored at start-of-line so JSDoc-example `from 'ajv'` strings in vendored chunks don't match.
1212
const VALIDATOR_BACKEND_IMPORT = /^import[^\n]*?from\s+["'](?:ajv|ajv-formats|@cfworker\/json-schema)["']/m;
13+
const ROOT_VALIDATOR_EXPORTS = ['AjvJsonSchemaValidator', 'CfWorkerJsonSchemaValidator', 'CfWorkerSchemaDraft'];
1314

1415
function chunkImportsOf(entryPath: string): string[] {
1516
const visited = new Set<string>();
@@ -27,6 +28,12 @@ function chunkImportsOf(entryPath: string): string[] {
2728
return [...visited];
2829
}
2930

31+
function rootExportBlockOf(content: string): string {
32+
const blocks = content.match(/(?:^|\n)export \{[\s\S]*?\};/g);
33+
expect(blocks).toBeTruthy();
34+
return blocks!.at(-1)!;
35+
}
36+
3037
describe('@modelcontextprotocol/client root entry is browser-safe', () => {
3138
beforeAll(() => {
3239
if (!existsSync(join(distDir, 'index.mjs')) || !existsSync(join(distDir, 'stdio.mjs'))) {
@@ -67,4 +74,13 @@ describe('@modelcontextprotocol/client root entry is browser-safe', () => {
6774
}
6875
}
6976
});
77+
78+
test('root declarations do not advertise validator provider classes', () => {
79+
for (const declaration of ['index.d.mts', 'index.d.cts']) {
80+
const rootExportBlock = rootExportBlockOf(readFileSync(join(distDir, declaration), 'utf8'));
81+
for (const symbol of ROOT_VALIDATOR_EXPORTS) {
82+
expect(rootExportBlock).not.toMatch(new RegExp(`\\b(?:type\\s+)?${symbol}\\b`));
83+
}
84+
}
85+
});
7086
});

packages/core-internal/src/exports/public/index.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,9 @@ export {
131131
export type { SpecTypeName, SpecTypes } from '../../types/specTypeSchema';
132132
export { isSpecType, specTypeSchemas } from '../../types/specTypeSchema';
133133
export type { StandardSchemaV1, StandardSchemaV1Sync, StandardSchemaWithJSON } from '../../util/standardSchema';
134-
// Validator providers are type-only here — import the runtime classes from the explicit
135-
// `@modelcontextprotocol/{client,server}/validators/{ajv,cf-worker}` subpaths to customise.
136-
export type { AjvJsonSchemaValidator } from '../../validators/ajvProvider';
137-
export type { CfWorkerJsonSchemaValidator, CfWorkerSchemaDraft } from '../../validators/cfWorkerProvider';
134+
// Validator provider classes stay subpath-only. Re-exporting them here, even as
135+
// `type`, can make generated root declarations advertise runtime-shaped root
136+
// exports that the package root does not provide.
138137
// fromJsonSchema is intentionally NOT exported here — the server and client packages
139138
// provide runtime-aware wrappers that default to the appropriate validator via _shims.
140139
export type { JsonSchemaType, JsonSchemaValidator, jsonSchemaValidator, JsonSchemaValidatorResult } from '../../validators/types';

packages/core-internal/src/index.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,8 @@ export * from './util/standardSchema';
3232
export * from './util/zodCompat';
3333
export { codecForVersion, MODERN_WIRE_REVISION } from './wire/codec';
3434

35-
// Validator providers are type-only here — import the runtime classes from the explicit
36-
// `@modelcontextprotocol/{client,server}/validators/{ajv,cf-worker}` subpaths to customise.
37-
export type { AjvJsonSchemaValidator } from './validators/ajvProvider';
38-
export type { CfWorkerJsonSchemaValidator, CfWorkerSchemaDraft } from './validators/cfWorkerProvider';
35+
// Validator provider classes stay subpath-only. Re-exporting them here, even as
36+
// `type`, can make generated client/server root declarations advertise
37+
// runtime-shaped root exports that the package root does not provide.
3938
export * from './validators/fromJsonSchema';
4039
export type { JsonSchemaType, JsonSchemaValidator, jsonSchemaValidator, JsonSchemaValidatorResult } from './validators/types';

packages/server/test/server/barrelClean.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const distDir = join(pkgDir, 'dist');
1010
const NODE_ONLY = /\b(child_process|cross-spawn|node:stream|node:child_process)\b/;
1111
// Anchored at start-of-line so JSDoc-example `from 'ajv'` strings in vendored chunks don't match.
1212
const VALIDATOR_BACKEND_IMPORT = /^import[^\n]*?from\s+["'](?:ajv|ajv-formats|@cfworker\/json-schema)["']/m;
13+
const ROOT_VALIDATOR_EXPORTS = ['AjvJsonSchemaValidator', 'CfWorkerJsonSchemaValidator', 'CfWorkerSchemaDraft'];
1314

1415
function chunkImportsOf(entryPath: string): string[] {
1516
const visited = new Set<string>();
@@ -27,6 +28,12 @@ function chunkImportsOf(entryPath: string): string[] {
2728
return [...visited];
2829
}
2930

31+
function rootExportBlockOf(content: string): string {
32+
const blocks = content.match(/(?:^|\n)export \{[\s\S]*?\};/g);
33+
expect(blocks).toBeTruthy();
34+
return blocks!.at(-1)!;
35+
}
36+
3037
describe('@modelcontextprotocol/server root entry is browser-safe', () => {
3138
beforeAll(() => {
3239
if (!existsSync(join(distDir, 'index.mjs')) || !existsSync(join(distDir, 'stdio.mjs'))) {
@@ -68,4 +75,13 @@ describe('@modelcontextprotocol/server root entry is browser-safe', () => {
6875
}
6976
}
7077
});
78+
79+
test('root declarations do not advertise validator provider classes', () => {
80+
for (const declaration of ['index.d.mts', 'index.d.cts']) {
81+
const rootExportBlock = rootExportBlockOf(readFileSync(join(distDir, declaration), 'utf8'));
82+
for (const symbol of ROOT_VALIDATOR_EXPORTS) {
83+
expect(rootExportBlock).not.toMatch(new RegExp(`\\b(?:type\\s+)?${symbol}\\b`));
84+
}
85+
}
86+
});
7187
});

0 commit comments

Comments
 (0)