Add localization/theming feature to 0.3 version
This commit is contained in:
parent
d595dd66dc
commit
1640adefe8
1 changed files with 559 additions and 18 deletions
|
|
@ -1,7 +1,7 @@
|
|||
import { readFileSync } from "fs";
|
||||
import { join } from "path";
|
||||
|
||||
import { McpbManifestSchema, v0_3 } from "../src/schemas/index.js";
|
||||
import { McpbManifestSchema, v0_2, v0_3 } from "../src/schemas/index.js";
|
||||
|
||||
describe("McpbManifestSchema", () => {
|
||||
it("should validate a valid manifest", () => {
|
||||
|
|
@ -35,9 +35,26 @@ describe("McpbManifestSchema", () => {
|
|||
}
|
||||
});
|
||||
|
||||
it("should accept a 0.2 manifest when upgraded to 0.3", () => {
|
||||
const manifestPath = join(__dirname, "valid-manifest-0.2.json");
|
||||
const manifestContent = readFileSync(manifestPath, "utf-8");
|
||||
const manifestData = JSON.parse(manifestContent);
|
||||
|
||||
const legacyResult = v0_2.McpbManifestSchema.safeParse(manifestData);
|
||||
expect(legacyResult.success).toBe(true);
|
||||
|
||||
const upgradedManifest = {
|
||||
...manifestData,
|
||||
manifest_version: "0.3",
|
||||
};
|
||||
const upgradedResult = v0_3.McpbManifestSchema.safeParse(upgradedManifest);
|
||||
|
||||
expect(upgradedResult.success).toBe(true);
|
||||
});
|
||||
|
||||
it("should validate manifest with all optional fields", () => {
|
||||
const fullManifest = {
|
||||
manifest_version: "0.2",
|
||||
manifest_version: "0.3",
|
||||
name: "full-extension",
|
||||
display_name: "Full Featured Extension",
|
||||
version: "2.0.0",
|
||||
|
|
@ -56,7 +73,23 @@ describe("McpbManifestSchema", () => {
|
|||
documentation: "https://docs.example.com",
|
||||
support: "https://support.example.com",
|
||||
icon: "icon.png",
|
||||
icons: [
|
||||
{
|
||||
src: "assets/icons/icon-16-light.png",
|
||||
sizes: "16x16",
|
||||
theme: "light",
|
||||
},
|
||||
{
|
||||
src: "assets/icons/icon-16-dark.png",
|
||||
sizes: "16x16",
|
||||
theme: "dark",
|
||||
},
|
||||
],
|
||||
screenshots: ["screenshot1.png", "screenshot2.png"],
|
||||
localization: {
|
||||
resources: "resources/${locale}.json",
|
||||
default_locale: "en-US",
|
||||
},
|
||||
server: {
|
||||
type: "python",
|
||||
entry_point: "main.py",
|
||||
|
|
@ -109,6 +142,8 @@ describe("McpbManifestSchema", () => {
|
|||
expect(result.data.tools).toHaveLength(1);
|
||||
expect(result.data.compatibility?.platforms).toContain("darwin");
|
||||
expect(result.data.user_config?.api_key.type).toBe("string");
|
||||
expect(result.data.icons).toHaveLength(2);
|
||||
expect(result.data.localization?.default_locale).toBe("en-US");
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -117,7 +152,7 @@ describe("McpbManifestSchema", () => {
|
|||
|
||||
serverTypes.forEach((type) => {
|
||||
const manifest = {
|
||||
manifest_version: "0.2",
|
||||
manifest_version: "0.3",
|
||||
name: "test",
|
||||
version: "1.0.0",
|
||||
description: "Test",
|
||||
|
|
@ -213,4 +248,92 @@ describe("McpbManifestSchema", () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe("localization", () => {
|
||||
const base = {
|
||||
manifest_version: "0.3" as const,
|
||||
name: "loc-ext",
|
||||
version: "1.0.0",
|
||||
description: "Test manifest",
|
||||
author: { name: "Author" },
|
||||
server: {
|
||||
type: "node" as const,
|
||||
entry_point: "server/index.js",
|
||||
mcp_config: { command: "node", args: ["server/index.js"] },
|
||||
},
|
||||
};
|
||||
|
||||
it("requires a ${locale} placeholder", () => {
|
||||
const manifest = {
|
||||
...base,
|
||||
localization: {
|
||||
resources: "resources/fr.json",
|
||||
default_locale: "en-US",
|
||||
},
|
||||
};
|
||||
const result = McpbManifestSchema.safeParse(manifest);
|
||||
expect(result.success).toBe(false);
|
||||
if (!result.success) {
|
||||
const messages = result.error.issues.map((issue) => issue.message);
|
||||
expect(messages.join(" ")).toContain("${locale}");
|
||||
}
|
||||
});
|
||||
|
||||
it("rejects invalid default locale", () => {
|
||||
const manifest = {
|
||||
...base,
|
||||
localization: {
|
||||
resources: "resources/${locale}.json",
|
||||
default_locale: "en_us",
|
||||
},
|
||||
};
|
||||
const result = McpbManifestSchema.safeParse(manifest);
|
||||
expect(result.success).toBe(false);
|
||||
});
|
||||
|
||||
it("accepts valid localization settings", () => {
|
||||
const manifest = {
|
||||
...base,
|
||||
localization: {
|
||||
resources: "resources/${locale}.json",
|
||||
default_locale: "en-US",
|
||||
},
|
||||
};
|
||||
const result = McpbManifestSchema.safeParse(manifest);
|
||||
expect(result.success).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("icons", () => {
|
||||
const base = {
|
||||
manifest_version: "0.3" as const,
|
||||
name: "icon-ext",
|
||||
version: "1.0.0",
|
||||
description: "Test manifest",
|
||||
author: { name: "Author" },
|
||||
server: {
|
||||
type: "python" as const,
|
||||
entry_point: "main.py",
|
||||
mcp_config: { command: "python", args: ["main.py"] },
|
||||
},
|
||||
};
|
||||
|
||||
it("rejects icons with invalid size format", () => {
|
||||
const manifest = {
|
||||
...base,
|
||||
icons: [{ src: "assets/icon.png", sizes: "16", theme: "light" }],
|
||||
};
|
||||
const result = McpbManifestSchema.safeParse(manifest);
|
||||
expect(result.success).toBe(false);
|
||||
});
|
||||
|
||||
it("allows icons without theme", () => {
|
||||
const manifest = {
|
||||
...base,
|
||||
icons: [{ src: "assets/icon.png", sizes: "128x128" }],
|
||||
};
|
||||
const result = McpbManifestSchema.safeParse(manifest);
|
||||
expect(result.success).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue