diff --git a/CHANGELOG.md b/CHANGELOG.md index b111010..2ff92f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Fixed + +- The VS Code extension icon fits within the Marketplace's 1024 × 1024 pixel limit, which blocked publishing 0.1.5 to the Marketplace. + ## 0.1.5 ### Fixed diff --git a/assets/icon.png b/assets/icon.png index 841d581..786bb48 100644 Binary files a/assets/icon.png and b/assets/icon.png differ diff --git a/test/vsix.spec.test.ts b/test/vsix.spec.test.ts index 8204bf7..481db67 100644 --- a/test/vsix.spec.test.ts +++ b/test/vsix.spec.test.ts @@ -4,7 +4,7 @@ import { readFile } from "node:fs/promises"; import { unzipSync } from "fflate"; -import { expect, it } from "vitest"; +import { assert, expect, it } from "vitest"; import { z } from "zod"; import { extensionArchivePath, @@ -12,6 +12,9 @@ import { } from "../scripts/package/metadata.js"; import { extensionFileList } from "./package/contents.js"; +// The Marketplace rejects a larger icon at publication. +const MAXIMUM_ICON_DIMENSION = 1_024; + it("contains only the extension runtime and required metadata", async () => { expect( Object.keys( @@ -72,3 +75,21 @@ it("targets the Busy Octopus UI extension", async () => { new Uint8Array(await readFile(manifest.icon)), ); }); + +it("keeps the icon within the Marketplace dimension limit", async () => { + const icon = unzipSync(new Uint8Array(await readFile(extensionArchivePath)))[ + `extension/${packageManifest.icon}` + ]; + + assert(icon !== undefined); + // A PNG signature is followed by the IHDR chunk, whose data starts with the width and height. + expect(Array.from(icon.subarray(0, 8))).toEqual([ + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, + ]); + expect(new TextDecoder().decode(icon.subarray(12, 16))).toBe("IHDR"); + + const view = new DataView(icon.buffer, icon.byteOffset, icon.byteLength); + + expect(view.getUint32(16)).toBeLessThanOrEqual(MAXIMUM_ICON_DIMENSION); + expect(view.getUint32(20)).toBeLessThanOrEqual(MAXIMUM_ICON_DIMENSION); +});