Skip to content

Commit 2d76201

Browse files
Export versioned schemas and validation utilities in browser bundle
- Update browser.ts to export validation utilities - Export McpbManifestSchema for backwards compatibility - Update config.ts to accept McpbManifestAny for broader manifest version support - Add validate.ts with version-aware validation functions 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 5fb25a2 commit 2d76201

File tree

4 files changed

+105
-3
lines changed

4 files changed

+105
-3
lines changed

src/browser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Browser-compatible exports
2-
export * from "./schemas/latest.js";
32
export * from "./schemas/index.js";
3+
export * from "./schemas/validate.js";
44
export * from "./shared/config.js";
55
export * from "./types.js";

src/schemas/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export * as vLatest from "./latest.js";
1010
export {
1111
MANIFEST_VERSION as LATEST_MANIFEST_VERSION,
1212
McpbManifestSchema as LatestMcpbManifestSchema,
13+
McpbManifestSchema, // backwards compatibility - exports latest schema
1314
} from "./latest.js";
1415

1516
/**

src/schemas/validate.ts

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import type * as z from "zod";
2+
3+
import * as v0_1 from "./0.1.js";
4+
import * as v0_2 from "./0.2.js";
5+
import * as v0_3 from "./0.3.js";
6+
7+
type McpbManifestV0_1 = z.infer<typeof v0_1.McpbManifestSchema>;
8+
type McpbManifestV0_2 = z.infer<typeof v0_2.McpbManifestSchema>;
9+
type McpbManifestV0_3 = z.infer<typeof v0_3.McpbManifestSchema>;
10+
11+
/**
12+
* Union type representing any supported manifest version.
13+
* This is the return type of validateManifest.
14+
*/
15+
type ValidatedManifest = McpbManifestV0_1 | McpbManifestV0_2 | McpbManifestV0_3;
16+
17+
/**
18+
* Validates a manifest using the appropriate schema based on its manifest_version.
19+
*
20+
* This function automatically detects the manifest version from the data and applies
21+
* the correct schema. This avoids TypeScript "excessively deep" errors that can occur
22+
* when using union schemas across package boundaries.
23+
*
24+
* @param data - The manifest data to validate
25+
* @returns The validated manifest with the correct type
26+
* @throws ZodError if validation fails
27+
*
28+
* @example
29+
* ```typescript
30+
* import { validateManifest } from '@anthropic-ai/mcpb/browser';
31+
*
32+
* const manifest = validateManifest(unknownData);
33+
* // manifest is typed as McpbManifestAny (union of all versions)
34+
* ```
35+
*/
36+
export function validateManifest(data: unknown): ValidatedManifest {
37+
// Read manifest_version or dxt_version from data
38+
const version = (data as any)?.manifest_version || (data as any)?.dxt_version;
39+
40+
// Use appropriate schema based on version
41+
if (version === "0.1") {
42+
return v0_1.McpbManifestSchema.parse(data);
43+
}
44+
45+
if (version === "0.2") {
46+
return v0_2.McpbManifestSchema.parse(data);
47+
}
48+
49+
// Default to latest version (0.3) if not specified or if version is "0.3"
50+
return v0_3.McpbManifestSchema.parse(data);
51+
}
52+
53+
/**
54+
* Validates a manifest using the appropriate schema, returning a Result-style object.
55+
*
56+
* @param data - The manifest data to validate
57+
* @returns An object with either { success: true, data } or { success: false, error }
58+
*
59+
* @example
60+
* ```typescript
61+
* import { validateManifestSafe } from '@anthropic-ai/mcpb/browser';
62+
*
63+
* const result = validateManifestSafe(unknownData);
64+
* if (result.success) {
65+
* console.log(result.data);
66+
* } else {
67+
* console.error(result.error);
68+
* }
69+
* ```
70+
*/
71+
export function validateManifestSafe(data: unknown):
72+
| { success: true; data: ValidatedManifest }
73+
| { success: false; error: unknown } {
74+
try {
75+
return { success: true, data: validateManifest(data) };
76+
} catch (error) {
77+
return { success: false, error };
78+
}
79+
}
80+
81+
/**
82+
* Get the appropriate schema for a given manifest version.
83+
* Useful when you need to work with the schema directly.
84+
*
85+
* @param version - The manifest version (e.g., "0.1", "0.2", "0.3")
86+
* @returns The schema for that version
87+
*
88+
* @example
89+
* ```typescript
90+
* import { getSchemaForVersion } from '@anthropic-ai/mcpb/browser';
91+
*
92+
* const schema = getSchemaForVersion("0.2");
93+
* const result = schema.safeParse(data);
94+
* ```
95+
*/
96+
export function getSchemaForVersion(version: "0.1" | "0.2" | "0.3") {
97+
if (version === "0.1") return v0_1.McpbManifestSchema;
98+
if (version === "0.2") return v0_2.McpbManifestSchema;
99+
return v0_3.McpbManifestSchema;
100+
}

src/shared/config.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type {
22
Logger,
33
McpbManifest,
4+
McpbManifestAny,
45
McpbUserConfigValues,
56
McpServerConfig,
67
} from "../types.js";
@@ -85,7 +86,7 @@ export function replaceVariables(
8586
}
8687

8788
interface GetMcpConfigForManifestOptions {
88-
manifest: McpbManifest;
89+
manifest: McpbManifestAny;
8990
extensionPath: string;
9091
systemDirs: Record<string, string>;
9192
userConfig: McpbUserConfigValues;
@@ -179,7 +180,7 @@ export async function getMcpConfigForManifest(
179180
}
180181

181182
interface HasRequiredConfigMissingOptions {
182-
manifest: McpbManifest;
183+
manifest: McpbManifestAny;
183184
userConfig?: McpbUserConfigValues;
184185
}
185186

0 commit comments

Comments
 (0)