Skip to content

Commit a9512a0

Browse files
committed
feat: redirect vite.plus vanity domain to installer scripts
Point the newly-attached vite.plus apex domain at the Vite+ install scripts so `curl https://vite.plus | sh` and `irm https://vite.plus/ps1 | iex` work as install entry points: https://vite.plus -> 302 https://viteplus.dev/install.sh https://vite.plus/ps1 -> 302 https://viteplus.dev/install.ps1 Implemented as a host-based middleware mirroring the existing 01.redirect-to-custom-domain pattern. Only the vite.plus apex host is matched; the canonical setup host, the legacy host, and localhost fall through untouched. Any non-/ps1 path defaults to install.sh.
1 parent 61b472c commit a9512a0

2 files changed

Lines changed: 70 additions & 0 deletions

File tree

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { defineMiddleware } from "void";
2+
3+
// The vite.plus vanity domain exists purely as an installer entry point:
4+
// curl https://vite.plus | sh -> shell installer
5+
// irm https://vite.plus/ps1 | iex -> PowerShell installer
6+
const INSTALL_HOST = "vite.plus";
7+
const INSTALL_SH = "https://viteplus.dev/install.sh";
8+
const INSTALL_PS1 = "https://viteplus.dev/install.ps1";
9+
10+
export function buildViteplusRedirect(host: string | undefined, requestUrl: string): string | null {
11+
if (host !== INSTALL_HOST) return null;
12+
const path = new URL(requestUrl).pathname.replace(/\/+$/, "");
13+
return path === "/ps1" ? INSTALL_PS1 : INSTALL_SH;
14+
}
15+
16+
export default defineMiddleware(async (c, next) => {
17+
const target = buildViteplusRedirect(c.req.header("host"), c.req.url);
18+
if (target) return c.redirect(target, 302);
19+
await next();
20+
});

tests/redirect-vite-plus.test.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { describe, expect, it } from "vite-plus/test";
2+
import { buildViteplusRedirect } from "../middleware/02.redirect-vite-plus";
3+
4+
describe("buildViteplusRedirect", () => {
5+
it("redirects the bare domain to the shell installer", () => {
6+
expect(buildViteplusRedirect("vite.plus", "https://vite.plus/")).toBe(
7+
"https://viteplus.dev/install.sh",
8+
);
9+
});
10+
11+
it("redirects /ps1 to the PowerShell installer", () => {
12+
expect(buildViteplusRedirect("vite.plus", "https://vite.plus/ps1")).toBe(
13+
"https://viteplus.dev/install.ps1",
14+
);
15+
});
16+
17+
it("tolerates a trailing slash on /ps1", () => {
18+
expect(buildViteplusRedirect("vite.plus", "https://vite.plus/ps1/")).toBe(
19+
"https://viteplus.dev/install.ps1",
20+
);
21+
});
22+
23+
it("redirects any other path to the shell installer", () => {
24+
expect(buildViteplusRedirect("vite.plus", "https://vite.plus/anything")).toBe(
25+
"https://viteplus.dev/install.sh",
26+
);
27+
});
28+
29+
it("ignores query strings when picking the target", () => {
30+
expect(buildViteplusRedirect("vite.plus", "https://vite.plus/?ref=docs")).toBe(
31+
"https://viteplus.dev/install.sh",
32+
);
33+
});
34+
35+
it("returns null for the canonical download host", () => {
36+
expect(buildViteplusRedirect("setup.viteplus.dev", "https://setup.viteplus.dev/")).toBeNull();
37+
});
38+
39+
it("returns null for the legacy host (handled by its own middleware)", () => {
40+
expect(buildViteplusRedirect("vp-setup.void.app", "https://vp-setup.void.app/")).toBeNull();
41+
});
42+
43+
it("returns null for localhost during dev", () => {
44+
expect(buildViteplusRedirect("localhost:5173", "http://localhost:5173/ps1")).toBeNull();
45+
});
46+
47+
it("returns null when the host header is missing", () => {
48+
expect(buildViteplusRedirect(undefined, "https://vite.plus/")).toBeNull();
49+
});
50+
});

0 commit comments

Comments
 (0)