Skip to content

Commit 37f05fe

Browse files
committed
Support assets and hardcode more repo names for better perf
1 parent 7a2c316 commit 37f05fe

6 files changed

Lines changed: 130 additions & 8 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
.claude
22
node_modules
3-
.wrangler
3+
.wrangler
4+
.dev.vars

README.md

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
Website for [https://plugins.dprint.dev](https://plugins.dprint.dev).
44

5-
This website is hosted on Cloudflare. I really dislike how that makes the code, but Cloudflare has free bandwidth, which is important for this project.
6-
75
## Redirect to Any GitHub Repo (For Plugin Authors)
86

97
This service provides a convenient URL for a plugin stored in any GitHub repo.
@@ -28,6 +26,24 @@ Restrictions and recommendations:
2826

2927
If your repo name is in the format `dprint-plugin-<something>` then you can omit `dprint-plugin-` in the `<repo_name>` for the redirect (ex. `https://plugins.dprint.dev/<user>/dprint-plugin-typescript-0.0.0.wasm` may be shortened to `https://plugins.dprint.dev/<user>/typescript-0.0.0.wasm`).
3028

29+
## Release Assets
30+
31+
For approved repositories, individual release assets can be served directly via:
32+
33+
```
34+
https://plugins.dprint.dev/<username>/<repo_name>/<tag_name>/asset/<asset_name>
35+
```
36+
37+
For example:
38+
39+
```
40+
https://plugins.dprint.dev/dprint/dprint-plugin-prettier/0.67.0/asset/dprint-plugin-prettier-x86_64-apple-darwin.zip
41+
```
42+
43+
This is useful for process plugins that distribute platform-specific binaries. Assets are cached in R2 for persistence.
44+
45+
Note: To get approved, open a PR to this repository including your username and plugin repo.
46+
3147
## Run Locally
3248

3349
```bash

handleRequest.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { renderHome } from "./home.jsx";
22
import oldMappings from "./old_redirects.json" with { type: "json" };
3-
import { tryResolveLatestJson, tryResolvePluginUrl, tryResolveSchemaUrl } from "./plugins.js";
3+
import { tryResolveAssetUrl, tryResolveLatestJson, tryResolvePluginUrl, tryResolveSchemaUrl } from "./plugins.js";
44
import { readInfoFile } from "./readInfoFile.js";
55
import styleCSS from "./style.css";
66
import { LruCache } from "./utils/LruCache.js";
@@ -15,13 +15,19 @@ const contentTypes = {
1515
json: "application/json; charset=utf-8",
1616
plain: "text/plain; charset=utf-8",
1717
wasm: "application/wasm",
18+
octetStream: "application/octet-stream",
1819
};
1920

2021
export function createRequestHandler() {
2122
const memoryCache = new LruCache<string, ArrayBuffer>({ size: 50 });
2223
return {
2324
async handleRequest(request: Request, ctx?: ExecutionContext) {
2425
const url = new URL(request.url);
26+
const assetUrl = tryResolveAssetUrl(url);
27+
if (assetUrl != null) {
28+
return servePlugin(request, assetUrl, contentTypes.octetStream, ctx);
29+
}
30+
2531
const githubUrl = await resolvePluginOrSchemaUrl(url);
2632
if (githubUrl != null) {
2733
const contentType = githubUrl.endsWith(".json") || githubUrl.endsWith(".exe-plugin")

plugins.test.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,42 @@
11
import { expect, it } from "vitest";
2-
import { tryResolveLatestJson } from "./plugins.js";
2+
import { tryResolveAssetUrl, tryResolveLatestJson } from "./plugins.js";
33
import { getLatestReleaseInfo } from "./utils/github.js";
44

5+
function resolveAsset(url: string) {
6+
return tryResolveAssetUrl(new URL(url));
7+
}
8+
9+
it("tryResolveAssetUrl", () => {
10+
// allowed repo
11+
expect(
12+
resolveAsset("https://plugins.dprint.dev/dprint/dprint-plugin-prettier/0.67.0/asset/dprint-plugin-prettier-x86_64-apple-darwin.zip"),
13+
).toEqual(
14+
"https://github.com/dprint/dprint-plugin-prettier/releases/download/0.67.0/dprint-plugin-prettier-x86_64-apple-darwin.zip",
15+
);
16+
17+
// latest tag is not allowed
18+
expect(
19+
resolveAsset("https://plugins.dprint.dev/dprint/dprint-plugin-prettier/latest/asset/dprint-plugin-prettier-x86_64-apple-darwin.zip"),
20+
).toEqual(undefined);
21+
22+
// different repo in dprint org also works
23+
expect(
24+
resolveAsset("https://plugins.dprint.dev/dprint/dprint-plugin-exec/0.5.0/asset/some-binary.zip"),
25+
).toEqual(
26+
"https://github.com/dprint/dprint-plugin-exec/releases/download/0.5.0/some-binary.zip",
27+
);
28+
29+
// org not on allow list
30+
expect(
31+
resolveAsset("https://plugins.dprint.dev/someone/some-repo/0.1.0/asset/file.zip"),
32+
).toEqual(undefined);
33+
34+
// non-matching URL
35+
expect(
36+
resolveAsset("https://plugins.dprint.dev/dprint/dprint-plugin-prettier/0.67.0/file.zip"),
37+
).toEqual(undefined);
38+
});
39+
540
it("tryResolveUserLatestJson", async () => {
641
// non-matching
742
expect(

plugins.ts

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,68 @@ const userSchemaPattern = new URLPattern({
2222
pathname: `/${userRepoPattern}/${tagPattern}/schema.json`,
2323
});
2424

25+
// known repos where shortname resolves to dprint-plugin-<name>,
26+
// avoiding a GitHub API call to check existence
27+
const KNOWN_DPRINT_PLUGIN_REPOS = new Set([
28+
// dprint org
29+
"dprint/dprint-plugin-typescript",
30+
"dprint/dprint-plugin-json",
31+
"dprint/dprint-plugin-markdown",
32+
"dprint/dprint-plugin-toml",
33+
"dprint/dprint-plugin-dockerfile",
34+
"dprint/dprint-plugin-biome",
35+
"dprint/dprint-plugin-oxc",
36+
"dprint/dprint-plugin-mago",
37+
"dprint/dprint-plugin-ruff",
38+
"dprint/dprint-plugin-jupyter",
39+
"dprint/dprint-plugin-prettier",
40+
"dprint/dprint-plugin-roslyn",
41+
"dprint/dprint-plugin-rustfmt",
42+
"dprint/dprint-plugin-yapf",
43+
"dprint/dprint-plugin-exec",
44+
"dprint/dprint-plugin-sql",
45+
// community
46+
"jakebailey/dprint-plugin-gofumpt",
47+
"malobre/dprint-plugin-vue",
48+
]);
49+
50+
// repos where the short name IS the repo name (no dprint-plugin- prefix)
51+
const KNOWN_NON_PREFIXED_REPOS = new Set([
52+
"g-plane/malva",
53+
"g-plane/markup_fmt",
54+
"g-plane/pretty_yaml",
55+
"g-plane/pretty_graphql",
56+
"lucacasonato/mf2-tools",
57+
]);
58+
59+
// orgs/users allowed to serve release assets directly
60+
const ASSET_ALLOWED_ORGS = new Set([
61+
"dprint",
62+
]);
63+
64+
const assetNamePattern = "([A-Za-z0-9\\-\\._]+)";
65+
const assetPattern = new URLPattern({
66+
pathname: `/${userRepoPattern}/${tagPattern}/asset/${assetNamePattern}`,
67+
});
68+
69+
export function tryResolveAssetUrl(url: URL) {
70+
const result = assetPattern.exec(url);
71+
if (!result) {
72+
return undefined;
73+
}
74+
const username = result.pathname.groups[0]!;
75+
const repo = result.pathname.groups[1]!;
76+
if (!ASSET_ALLOWED_ORGS.has(username)) {
77+
return undefined;
78+
}
79+
const tag = result.pathname.groups[2]!;
80+
if (tag === "latest") {
81+
return undefined;
82+
}
83+
const assetName = result.pathname.groups[3]!;
84+
return `https://github.com/${username}/${repo}/releases/download/${tag}/${assetName}`;
85+
}
86+
2587
export async function tryResolvePluginUrl(url: URL) {
2688
return dprintPluginTagPatternMapper(dprintWasmPluginPattern, url, "plugin.wasm")
2789
?? dprintPluginTagPatternMapper(dprintProcessPluginPattern, url, "plugin.json")
@@ -132,8 +194,10 @@ async function getFullRepoName(username: string, repoName: string) {
132194
return repoName;
133195
}
134196
const fullName = `dprint-plugin-${repoName}`;
135-
// todo: hardcode more repos here
136-
if (username === "jakebailey" && fullName === "dprint-plugin-gofumpt") {
197+
if (KNOWN_NON_PREFIXED_REPOS.has(`${username}/${repoName}`)) {
198+
return repoName;
199+
}
200+
if (KNOWN_DPRINT_PLUGIN_REPOS.has(`${username}/${fullName}`)) {
137201
return fullName;
138202
}
139203
if (await checkGithubRepoExists(username, fullName)) {

wrangler.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "dprint-plugins"
22
main = "main.ts"
3-
compatibility_date = "2024-12-01"
3+
compatibility_date = "2024-02-24"
44
compatibility_flags = ["nodejs_compat"]
55

66
rules = [

0 commit comments

Comments
 (0)