From 55e3c3cfd8157db263c9bcf56601b2e2d34e8421 Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Thu, 30 Oct 2025 07:53:06 -0500 Subject: [PATCH] fix: resolve linting errors - Remove duplicate node:path import in test/icon-validation.test.ts - Replace 4 instances of 'any' type with 'unknown' in error handlers - Auto-format code with prettier (27 formatting fixes) Addresses review feedback from PR #136 All 6 errors and 27 warnings resolved --- schemas/mcpb-manifest-v0.2.schema.json | 53 +--------- src/node/validate.ts | 2 +- test/cli.test.ts | 19 ++-- test/icon-validation.test.ts | 131 ++++++++++++++++++------- 4 files changed, 109 insertions(+), 96 deletions(-) diff --git a/schemas/mcpb-manifest-v0.2.schema.json b/schemas/mcpb-manifest-v0.2.schema.json index a2dc082..fc522b9 100644 --- a/schemas/mcpb-manifest-v0.2.schema.json +++ b/schemas/mcpb-manifest-v0.2.schema.json @@ -6,12 +6,12 @@ }, "dxt_version": { "type": "string", - "const": "0.3", + "const": "0.2", "description": "@deprecated Use manifest_version instead" }, "manifest_version": { "type": "string", - "const": "0.3" + "const": "0.2" }, "name": { "type": "string" @@ -80,54 +80,12 @@ "icon": { "type": "string" }, - "icons": { - "type": "array", - "items": { - "type": "object", - "properties": { - "src": { - "type": "string" - }, - "sizes": { - "type": "string", - "pattern": "^\\d+x\\d+$" - }, - "theme": { - "type": "string", - "minLength": 1 - } - }, - "required": [ - "src", - "sizes" - ], - "additionalProperties": false - } - }, "screenshots": { "type": "array", "items": { "type": "string" } }, - "localization": { - "type": "object", - "properties": { - "resources": { - "type": "string", - "pattern": "\\$\\{locale\\}" - }, - "default_locale": { - "type": "string", - "pattern": "^[A-Za-z0-9]{2,8}(?:-[A-Za-z0-9]{1,8})*$" - } - }, - "required": [ - "resources", - "default_locale" - ], - "additionalProperties": false - }, "server": { "type": "object", "properties": { @@ -355,13 +313,6 @@ ], "additionalProperties": false } - }, - "_meta": { - "type": "object", - "additionalProperties": { - "type": "object", - "additionalProperties": {} - } } }, "required": [ diff --git a/src/node/validate.ts b/src/node/validate.ts index a5f2633..ac21747 100644 --- a/src/node/validate.ts +++ b/src/node/validate.ts @@ -59,7 +59,7 @@ function validateIcon( // Check for ${__dirname} variable (error - doesn't work) if (hasVariableSubstitution) { errors.push( - 'Icon path should not use ${__dirname} variable substitution. ' + + "Icon path should not use ${__dirname} variable substitution. " + 'Use a simple relative path like "icon.png" instead of "${__dirname}/icon.png".', ); } diff --git a/test/cli.test.ts b/test/cli.test.ts index d9dfa92..9bdc1eb 100644 --- a/test/cli.test.ts +++ b/test/cli.test.ts @@ -91,15 +91,12 @@ describe("DXT CLI", () => { // Create a valid PNG file (1x1 transparent pixel) const validPngBuffer = Buffer.from([ - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, - 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0x15, 0xc4, - 0x89, 0x00, 0x00, 0x00, 0x0a, 0x49, 0x44, 0x41, - 0x54, 0x78, 0x9c, 0x63, 0x00, 0x01, 0x00, 0x00, - 0x05, 0x00, 0x01, 0x0d, 0x0a, 0x2d, 0xb4, 0x00, - 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, - 0x42, 0x60, 0x82, + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0x15, 0xc4, 0x89, 0x00, 0x00, 0x00, + 0x0a, 0x49, 0x44, 0x41, 0x54, 0x78, 0x9c, 0x63, 0x00, 0x01, 0x00, 0x00, + 0x05, 0x00, 0x01, 0x0d, 0x0a, 0x2d, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x49, + 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, ]); fs.writeFileSync(join(testDir, "icon.png"), validPngBuffer); }); @@ -127,7 +124,7 @@ describe("DXT CLI", () => { entry_point: "server/index.js", mcp_config: { command: "node" }, }, - }) + }), ); const result = execSync(`node ${cliPath} validate ${manifestWithIcon}`, { @@ -154,7 +151,7 @@ describe("DXT CLI", () => { entry_point: "server/index.js", mcp_config: { command: "node" }, }, - }) + }), ); const result = execSync(`node ${cliPath} validate ${manifestWithUrl}`, { diff --git a/test/icon-validation.test.ts b/test/icon-validation.test.ts index ac4e4ed..b55abd4 100644 --- a/test/icon-validation.test.ts +++ b/test/icon-validation.test.ts @@ -1,7 +1,6 @@ import { execSync } from "node:child_process"; import fs from "node:fs"; import { join } from "node:path"; -import path from "node:path"; describe("Icon Validation", () => { const cliPath = join(__dirname, "../dist/cli/cli.js"); @@ -18,20 +17,81 @@ describe("Icon Validation", () => { // Create a valid PNG file (1x1 transparent pixel) const validPngBuffer = Buffer.from([ - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, // PNG signature - 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, // IHDR chunk - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, // 1x1 dimensions - 0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0x15, 0xc4, - 0x89, 0x00, 0x00, 0x00, 0x0a, 0x49, 0x44, 0x41, - 0x54, 0x78, 0x9c, 0x63, 0x00, 0x01, 0x00, 0x00, - 0x05, 0x00, 0x01, 0x0d, 0x0a, 0x2d, 0xb4, 0x00, - 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, - 0x42, 0x60, 0x82, + 0x89, + 0x50, + 0x4e, + 0x47, + 0x0d, + 0x0a, + 0x1a, + 0x0a, // PNG signature + 0x00, + 0x00, + 0x00, + 0x0d, + 0x49, + 0x48, + 0x44, + 0x52, // IHDR chunk + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x01, // 1x1 dimensions + 0x08, + 0x06, + 0x00, + 0x00, + 0x00, + 0x1f, + 0x15, + 0xc4, + 0x89, + 0x00, + 0x00, + 0x00, + 0x0a, + 0x49, + 0x44, + 0x41, + 0x54, + 0x78, + 0x9c, + 0x63, + 0x00, + 0x01, + 0x00, + 0x00, + 0x05, + 0x00, + 0x01, + 0x0d, + 0x0a, + 0x2d, + 0xb4, + 0x00, + 0x00, + 0x00, + 0x00, + 0x49, + 0x45, + 0x4e, + 0x44, + 0xae, + 0x42, + 0x60, + 0x82, ]); fs.writeFileSync(join(testFixturesDir, "valid-icon.png"), validPngBuffer); // Create an invalid (non-PNG) file - fs.writeFileSync(join(testFixturesDir, "invalid-icon.jpg"), "Not a PNG file"); + fs.writeFileSync( + join(testFixturesDir, "invalid-icon.jpg"), + "Not a PNG file", + ); // Create test manifests createTestManifest("valid-local-icon.json", { @@ -92,7 +152,7 @@ describe("Icon Validation", () => { fs.writeFileSync( join(testFixturesDir, filename), - JSON.stringify(manifest, null, 2) + JSON.stringify(manifest, null, 2), ); } @@ -135,7 +195,10 @@ describe("Icon Validation", () => { }); it("should reject icons with ${__dirname} variable", () => { - const manifestPath = join(testFixturesDir, "invalid-dirname-variable.json"); + const manifestPath = join( + testFixturesDir, + "invalid-dirname-variable.json", + ); expect(() => { execSync(`node ${cliPath} validate ${manifestPath}`, { @@ -149,8 +212,9 @@ describe("Icon Validation", () => { encoding: "utf-8", stdio: "pipe", }); - } catch (error: any) { - const output = error.stdout?.toString() || ""; + } catch (error: unknown) { + const execError = error as { stdout?: Buffer; stderr?: Buffer }; + const output = execError.stdout?.toString() || ""; expect(output).toContain("Icon validation failed"); expect(output).toContain("${__dirname}"); expect(output).toContain("simple relative path"); @@ -172,8 +236,9 @@ describe("Icon Validation", () => { encoding: "utf-8", stdio: "pipe", }); - } catch (error: any) { - const output = error.stdout?.toString() || ""; + } catch (error: unknown) { + const execError = error as { stdout?: Buffer; stderr?: Buffer }; + const output = execError.stdout?.toString() || ""; expect(output).toContain("Icon validation failed"); expect(output).toContain("relative to the bundle root"); } @@ -194,8 +259,9 @@ describe("Icon Validation", () => { encoding: "utf-8", stdio: "pipe", }); - } catch (error: any) { - const output = error.stdout?.toString() || ""; + } catch (error: unknown) { + const execError = error as { stdout?: Buffer; stderr?: Buffer }; + const output = execError.stdout?.toString() || ""; expect(output).toContain("Icon validation failed"); expect(output).toContain("not found"); } @@ -216,8 +282,9 @@ describe("Icon Validation", () => { encoding: "utf-8", stdio: "pipe", }); - } catch (error: any) { - const output = error.stdout?.toString() || ""; + } catch (error: unknown) { + const execError = error as { stdout?: Buffer; stderr?: Buffer }; + const output = execError.stdout?.toString() || ""; expect(output).toContain("Icon validation failed"); expect(output).toContain("PNG format"); } @@ -233,15 +300,12 @@ describe("Icon Validation", () => { } const validPngBuffer = Buffer.from([ - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, - 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0x15, 0xc4, - 0x89, 0x00, 0x00, 0x00, 0x0a, 0x49, 0x44, 0x41, - 0x54, 0x78, 0x9c, 0x63, 0x00, 0x01, 0x00, 0x00, - 0x05, 0x00, 0x01, 0x0d, 0x0a, 0x2d, 0xb4, 0x00, - 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, - 0x42, 0x60, 0x82, + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0x15, 0xc4, 0x89, 0x00, 0x00, 0x00, + 0x0a, 0x49, 0x44, 0x41, 0x54, 0x78, 0x9c, 0x63, 0x00, 0x01, 0x00, 0x00, + 0x05, 0x00, 0x01, 0x0d, 0x0a, 0x2d, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x49, + 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, ]); fs.writeFileSync(join(assetsDir, "icon.png"), validPngBuffer); @@ -249,7 +313,10 @@ describe("Icon Validation", () => { icon: "assets/icon.png", }); - const manifestPath = join(testFixturesDir, "valid-subdirectory-icon.json"); + const manifestPath = join( + testFixturesDir, + "valid-subdirectory-icon.json", + ); const result = execSync(`node ${cliPath} validate ${manifestPath}`, { encoding: "utf-8", }); @@ -258,6 +325,4 @@ describe("Icon Validation", () => { expect(result).toContain("Icon validation passed"); }); }); - }); -