From 49c856c91210869b814ae9f5fc72bf5b4ff85473 Mon Sep 17 00:00:00 2001 From: David Sherret Date: Wed, 25 Mar 2026 11:51:47 -0400 Subject: [PATCH] Redirect process plugin .json file to asset url path --- handleRequest.test.ts | 19 +++++++++++++++++++ handleRequest.ts | 21 +++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/handleRequest.test.ts b/handleRequest.test.ts index 4396453..c26373e 100644 --- a/handleRequest.test.ts +++ b/handleRequest.test.ts @@ -326,6 +326,25 @@ it("tryResolvePluginUrl", async () => { ); }); +it("should redirect non-wasm plugins to asset URL", async () => { + const { handleRequest } = createRequestHandler(); + const response = await handleRequest( + new Request("https://plugins.dprint.dev/prettier-0.7.0.json"), + ); + expect(response.status).toEqual(302); + expect(response.headers.get("location")).toEqual( + "https://plugins.dprint.dev/dprint/dprint-plugin-prettier/0.7.0/asset/plugin.json", + ); +}); + +it("should not redirect wasm plugins", async () => { + const { handleRequest } = createRequestHandler(); + const response = await handleRequest( + new Request("https://plugins.dprint.dev/typescript-0.62.2.wasm"), + ); + expect(response.status).not.toEqual(302); +}); + it("should return 404 for asset not found", async () => { const { handleRequest } = createRequestHandler(); const response = await handleRequest( diff --git a/handleRequest.ts b/handleRequest.ts index a245c5a..2b878fb 100644 --- a/handleRequest.ts +++ b/handleRequest.ts @@ -31,6 +31,14 @@ export function createRequestHandler() { const githubUrl = await resolvePluginOrSchemaUrl(url); if (githubUrl != null) { + if (!githubUrl.endsWith(".wasm")) { + // redirect non-wasm files to asset URL so relative URLs in + // plugin.json files resolve correctly + const assetPath = githubUrlToAssetPath(githubUrl); + if (assetPath != null) { + return Response.redirect(new URL(assetPath, url.origin).href, 302); + } + } return servePlugin(request, githubUrl, ctx); } @@ -192,6 +200,19 @@ function createJsonResponse(text: string, request: Request) { }); } +// converts a GitHub release URL to a local asset path +// e.g. https://github.com/dprint/dprint-plugin-prettier/releases/download/0.7.0/plugin.json +// -> /dprint/dprint-plugin-prettier/0.7.0/asset/plugin.json +const githubReleasePattern = /^https:\/\/github\.com\/([^/]+)\/([^/]+)\/releases\/download\/([^/]+)\/(.+)$/; +function githubUrlToAssetPath(githubUrl: string) { + const match = githubReleasePattern.exec(githubUrl); + if (match == null) { + return undefined; + } + const [, username, repo, tag, fileName] = match; + return `/${username}/${repo}/${tag}/asset/${fileName}`; +} + function contentTypeForUrl(url: string) { if (url.endsWith(".wasm")) return contentTypes.wasm; if (url.endsWith(".json") || url.endsWith(".exe-plugin")) return contentTypes.json;