diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..8feeeb7 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,14 @@ +name: CI +on: push +jobs: + test: + name: CI + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - uses: denoland/setup-deno@v1 + with: + deno-version: v1.x + - name: Run tests + run: deno test --allow-env --allow-read=. --allow-net=api.github.com diff --git a/deno.json b/deno.json new file mode 100644 index 0000000..270aa72 --- /dev/null +++ b/deno.json @@ -0,0 +1,7 @@ +{ + "imports": { + "preact": "https://esm.sh/preact@10.15.1", + "preact/": "https://esm.sh/preact@10.15.1/", + "preact-render-to-string": "https://esm.sh/*preact-render-to-string@6.1.0" + } +} diff --git a/deno.lock b/deno.lock new file mode 100644 index 0000000..d1f41ad --- /dev/null +++ b/deno.lock @@ -0,0 +1,24 @@ +{ + "version": "2", + "remote": { + "https://deno.land/std@0.117.0/fmt/colors.ts": "8368ddf2d48dfe413ffd04cdbb7ae6a1009cf0dccc9c7ff1d76259d9c61a0621", + "https://deno.land/std@0.117.0/testing/_diff.ts": "e6a10d2aca8d6c27a9c5b8a2dbbf64353874730af539707b5b39d4128140642d", + "https://deno.land/std@0.117.0/testing/asserts.ts": "a1fef0239a2c343b0baa49c77dcdd7412613c46f3aba2887c331a2d7ed1f645e", + "https://deno.land/std@0.122.0/async/deadline.ts": "1d6ac7aeaee22f75eb86e4e105d6161118aad7b41ae2dd14f4cfd3bf97472b93", + "https://deno.land/std@0.122.0/async/debounce.ts": "b2f693e4baa16b62793fd618de6c003b63228db50ecfe3bd51fc5f6dc0bc264b", + "https://deno.land/std@0.122.0/async/deferred.ts": "ab60d46ba561abb3b13c0c8085d05797a384b9f182935f051dc67136817acdee", + "https://deno.land/std@0.122.0/async/delay.ts": "f2d8ccaa8ebc26594bd8b0989edfd8a96257a714c1dee2fb54d986e5bdd840ac", + "https://deno.land/std@0.122.0/async/mod.ts": "78425176fabea7bd1046ce3819fd69ce40da85c83e0f174d17e8e224a91f7d10", + "https://deno.land/std@0.122.0/async/mux_async_iterator.ts": "62abff3af9ff619e8f2adc96fc70d4ca020fa48a50c23c13f12d02ed2b760dbe", + "https://deno.land/std@0.122.0/async/pool.ts": "353ce4f91865da203a097aa6f33de8966340c91b6f4a055611c8c5d534afd12f", + "https://deno.land/std@0.122.0/async/tee.ts": "3e9f2ef6b36e55188de16a667c702ace4ad0cf84e3720379160e062bf27348ad", + "https://deno.land/std@0.122.0/http/server.ts": "4d88a15537ef207968aef62ea8b16212c10950b3f83793ec0391defa2981fbcb", + "https://esm.sh/*preact-render-to-string@6.1.0": "9499dc7f262a542ed272bba52733bb6aa3365fbf2b2733b0d7ecd6da102fa290", + "https://esm.sh/preact@10.15.1": "2b79349676a4942fbcf835c4efa909791c2f0aeca195225bf22bac9866e94b4e", + "https://esm.sh/stable/preact@10.15.1/denonext/preact.mjs": "30710ac1d5ff3711ae0c04eddbeb706f34f82d97489f61aaf09897bc75d2a628", + "https://esm.sh/v118/preact@10.15.1/src/index.d.ts": "fa83186a4b6caca36d52ca2d49b481c3ca5460988d4a8388d44dadc28987fb27", + "https://esm.sh/v118/preact@10.15.1/src/jsx.d.ts": "a6e4b7e4af3b959f8cfd41a0f475c547807ebcec8524d9605ab5c6de79f302fa", + "https://esm.sh/v126/preact-render-to-string@6.1.0/X-ZS8q/denonext/preact-render-to-string.mjs": "8ce71d44f2a197f8fafa24c8d1ac19e0d7fac5a171efae6154f8d754e1ae0ae4", + "https://esm.sh/v126/preact-render-to-string@6.1.0/X-ZS8q/src/index.d.ts": "b8fafa9f8ae9069eff148da320ed56acd5c3c95112c5e03d4796e15ac76b974c" + } +} diff --git a/dprint.json b/dprint.json index 34447a2..2113152 100644 --- a/dprint.json +++ b/dprint.json @@ -7,9 +7,9 @@ "**/*-lock.json" ], "plugins": [ - "https://plugins.dprint.dev/typescript-0.68.0.wasm", - "https://plugins.dprint.dev/json-0.15.1.wasm", - "https://plugins.dprint.dev/markdown-0.13.1.wasm", - "https://plugins.dprint.dev/prettier-0.7.0.json@4e846f43b32981258cef5095b3d732522947592e090ef52333801f9d6e8adb33" + "https://plugins.dprint.dev/typescript-0.85.0.wasm", + "https://plugins.dprint.dev/json-0.17.4.wasm", + "https://plugins.dprint.dev/markdown-0.15.3.wasm", + "https://plugins.dprint.dev/prettier-0.26.1.json@fdbe31f6aecd24f9d6b924214710a6766050d03146163b4e241e6056b2462f2e" ] } diff --git a/handleRequest.test.ts b/handleRequest.test.ts index a115c0d..87b7fff 100644 --- a/handleRequest.test.ts +++ b/handleRequest.test.ts @@ -320,6 +320,15 @@ Deno.test("tryResolvePluginUrl", async () => { ); }); +Deno.test("should redirect when the url has an @ sign in it", async () => { + assertEquals( + await getRedirectUrl( + "https://plugins.dprint.dev/prettier-0.24.0.json@9a57d0d8e440ad90d07a503166af47e7a6a886abd46767933f9c279f72468596", + ), + "https://plugins.dprint.dev/prettier-0.24.0.json", + ); +}); + // todo: mock github api for these tests Deno.test("tryResolveSchemaUrl", async () => { diff --git a/handleRequest.ts b/handleRequest.ts index b2ae5d3..0130799 100644 --- a/handleRequest.ts +++ b/handleRequest.ts @@ -14,6 +14,15 @@ const contentTypes = { export async function handleRequest(request: Request) { const url = new URL(request.url); + const atSignIndex = url.pathname.lastIndexOf("@"); + if (atSignIndex >= 0 && url.pathname.length - atSignIndex === 65) { + return redirectWithoutHash(url, atSignIndex); + } + if (url.pathname.includes("testing-this-out")) { + return new Response((Deno.env.get("DPRINT_PLUGINS_GH_TOKEN")?.length ?? 0).toString(), { + status: 200, + }); + } const newUrl = await resolvePluginOrSchemaUrl(url); if (newUrl != null) { const contentType = newUrl.endsWith(".json") @@ -161,3 +170,8 @@ function create404Response() { statusText: "Not Found", }); } + +function redirectWithoutHash(url: URL, atSignIndex: number) { + const newUrl = new URL(url.pathname.slice(0, atSignIndex), url); + return createRedirectResponse(newUrl.toString()); +} diff --git a/home.tsx b/home.tsx index 75ed106..9c97b8e 100644 --- a/home.tsx +++ b/home.tsx @@ -1,6 +1,6 @@ /** @jsx h */ -import { h } from "https://x.lcas.dev/preact@10.5.12/mod.js"; -import { renderToString } from "https://x.lcas.dev/preact@10.5.12/ssr.js"; +import { h } from "preact"; +import { renderToString } from "preact-render-to-string"; import { PluginData, PluginsData, readInfoFile } from "./readInfoFile.ts"; export async function renderHome() { diff --git a/plugins.ts b/plugins.ts index ed1b6cc..41442e0 100644 --- a/plugins.ts +++ b/plugins.ts @@ -41,8 +41,8 @@ export async function tryResolveLatestJson(url: URL) { if (!result) { return undefined; } - const username = result.pathname.groups[0]; - const shortRepoName = result.pathname.groups[1]; + const username = result.pathname.groups[0]!; + const shortRepoName = result.pathname.groups[1]!; const latestInfo = await getLatestInfo(username, shortRepoName); if (latestInfo == null) { return 404; @@ -104,8 +104,8 @@ async function userRepoTagPatternMapper( ) { const result = pattern.exec(url); if (result) { - const username = result.pathname.groups[0]; - const repo = await getFullRepoName(username, result.pathname.groups[1]); + const username = result.pathname.groups[0]!; + const repo = await getFullRepoName(username, result.pathname.groups[1]!); const tag = result.pathname.groups[2]; if (tag === "latest") { return `https://github.com/${username}/${repo}/releases/latest/download/${fileName}`;