Archived
fix: preserve extension-only plugin asset MIME types
This commit is contained in:
@@ -44,6 +44,22 @@ describe("PiWebPluginService", () => {
|
|||||||
expect(asset?.content.toString("utf8")).toContain("export default");
|
expect(asset?.content.toString("utf8")).toContain("export default");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("preserves content types for extension-only asset names", async () => {
|
||||||
|
const pluginDir = join(tempDir, "plugins", "extension-only");
|
||||||
|
await writePlugin(pluginDir, {
|
||||||
|
packageJson: { piWeb: { plugins: [{ id: "extension-only", module: ".js" }] } },
|
||||||
|
files: {
|
||||||
|
".js": "export default {};",
|
||||||
|
".svg": '<svg xmlns="http://www.w3.org/2000/svg"></svg>',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const service = new PiWebPluginService({ roots: [{ path: join(tempDir, "plugins"), source: "test", scope: "local" }], packageProvider: false });
|
||||||
|
|
||||||
|
await expect(service.readAsset("extension-only", ".js")).resolves.toMatchObject({ contentType: "application/javascript; charset=utf-8" });
|
||||||
|
await expect(service.readAsset("extension-only", ".svg")).resolves.toMatchObject({ contentType: "image/svg+xml" });
|
||||||
|
});
|
||||||
|
|
||||||
it("serves nested SVG assets with a browser-compatible content type", async () => {
|
it("serves nested SVG assets with a browser-compatible content type", async () => {
|
||||||
const pluginDir = join(tempDir, "plugins", "icons");
|
const pluginDir = join(tempDir, "plugins", "icons");
|
||||||
const svg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"></svg>';
|
const svg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"></svg>';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { existsSync } from "node:fs";
|
import { existsSync } from "node:fs";
|
||||||
import { readdir, readFile, realpath, stat } from "node:fs/promises";
|
import { readdir, readFile, realpath, stat } from "node:fs/promises";
|
||||||
import { dirname, extname, join, relative, resolve, sep } from "node:path";
|
import { dirname, join, relative, resolve, sep } from "node:path";
|
||||||
import { fileURLToPath } from "node:url";
|
import { fileURLToPath } from "node:url";
|
||||||
import { DefaultPackageManager, getAgentDir, SettingsManager } from "@earendil-works/pi-coding-agent";
|
import { DefaultPackageManager, getAgentDir, SettingsManager } from "@earendil-works/pi-coding-agent";
|
||||||
import { loadPiWebConfig, piWebDataDir, type PiWebConfig } from "../config.js";
|
import { loadPiWebConfig, piWebDataDir, type PiWebConfig } from "../config.js";
|
||||||
@@ -335,14 +335,13 @@ function isWithin(root: string, candidate: string): boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function contentTypeFor(path: string): string {
|
function contentTypeFor(path: string): string {
|
||||||
switch (extname(path).toLowerCase()) {
|
const lowerPath = path.toLowerCase();
|
||||||
case ".js": return "application/javascript; charset=utf-8";
|
if (lowerPath.endsWith(".js")) return "application/javascript; charset=utf-8";
|
||||||
case ".json": return "application/json; charset=utf-8";
|
if (lowerPath.endsWith(".json")) return "application/json; charset=utf-8";
|
||||||
case ".css": return "text/css; charset=utf-8";
|
if (lowerPath.endsWith(".css")) return "text/css; charset=utf-8";
|
||||||
case ".html": return "text/html; charset=utf-8";
|
if (lowerPath.endsWith(".html")) return "text/html; charset=utf-8";
|
||||||
case ".svg": return "image/svg+xml";
|
if (lowerPath.endsWith(".svg")) return "image/svg+xml";
|
||||||
default: return "application/octet-stream";
|
return "application/octet-stream";
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function isRecord(value: unknown): value is Record<string, unknown> {
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||||
|
|||||||
Reference in New Issue
Block a user