Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions middleware/02.redirect-vite-plus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { defineMiddleware } from "void";

// The vite.plus vanity domain exists purely as an installer entry point:
// curl https://vite.plus | sh -> shell installer
// irm https://vite.plus/ps1 | iex -> PowerShell installer
const INSTALL_HOST = "vite.plus";
const INSTALL_SH = "https://viteplus.dev/install.sh";
const INSTALL_PS1 = "https://viteplus.dev/install.ps1";

export function buildViteplusRedirect(host: string | undefined, requestUrl: string): string | null {
if (host !== INSTALL_HOST) return null;
const path = new URL(requestUrl).pathname.replace(/\/+$/, "");
return path === "/ps1" ? INSTALL_PS1 : INSTALL_SH;
}

export default defineMiddleware(async (c, next) => {
const target = buildViteplusRedirect(c.req.header("host"), c.req.url);
if (target) return c.redirect(target, 302);
await next();
});
50 changes: 50 additions & 0 deletions tests/redirect-vite-plus.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { describe, expect, it } from "vite-plus/test";
import { buildViteplusRedirect } from "../middleware/02.redirect-vite-plus";

describe("buildViteplusRedirect", () => {
it("redirects the bare domain to the shell installer", () => {
expect(buildViteplusRedirect("vite.plus", "https://vite.plus/")).toBe(
"https://viteplus.dev/install.sh",
);
});

it("redirects /ps1 to the PowerShell installer", () => {
expect(buildViteplusRedirect("vite.plus", "https://vite.plus/ps1")).toBe(
"https://viteplus.dev/install.ps1",
);
});

it("tolerates a trailing slash on /ps1", () => {
expect(buildViteplusRedirect("vite.plus", "https://vite.plus/ps1/")).toBe(
"https://viteplus.dev/install.ps1",
);
});

it("redirects any other path to the shell installer", () => {
expect(buildViteplusRedirect("vite.plus", "https://vite.plus/anything")).toBe(
"https://viteplus.dev/install.sh",
);
});

it("ignores query strings when picking the target", () => {
expect(buildViteplusRedirect("vite.plus", "https://vite.plus/?ref=docs")).toBe(
"https://viteplus.dev/install.sh",
);
});

it("returns null for the canonical download host", () => {
expect(buildViteplusRedirect("setup.viteplus.dev", "https://setup.viteplus.dev/")).toBeNull();
});

it("returns null for the legacy host (handled by its own middleware)", () => {
expect(buildViteplusRedirect("vp-setup.void.app", "https://vp-setup.void.app/")).toBeNull();
});

it("returns null for localhost during dev", () => {
expect(buildViteplusRedirect("localhost:5173", "http://localhost:5173/ps1")).toBeNull();
});

it("returns null when the host header is missing", () => {
expect(buildViteplusRedirect(undefined, "https://vite.plus/")).toBeNull();
});
});