fix: handle docs demo app route

This commit is contained in:
3252a8
2026-05-28 23:33:40 +03:00
parent 5892a72575
commit 913b2d428e
5 changed files with 98 additions and 90 deletions
+6
View File
@@ -1,7 +1,13 @@
# Cloudflare Pages rewrites for the static docs demo SPA. # Cloudflare Pages rewrites for the static docs demo SPA.
# Keep these scoped to app routes so runtime JS/CSS/assets are served directly. # Keep these scoped to app routes so runtime JS/CSS/assets are served directly.
/demo /demo/index.html 200
/demo/ /demo/index.html 200
/demo/app /demo/index.html 200
/demo/app/ /demo/index.html 200
/demo/runtime /demo/runtime/app.html 200 /demo/runtime /demo/runtime/app.html 200
/demo/runtime/ /demo/runtime/app.html 200 /demo/runtime/ /demo/runtime/app.html 200
/demo/runtime/app /demo/runtime/app.html 200
/demo/runtime/app/ /demo/runtime/app.html 200
/demo/runtime/home /demo/runtime/app.html 200 /demo/runtime/home /demo/runtime/app.html 200
/demo/runtime/home/* /demo/runtime/app.html 200 /demo/runtime/home/* /demo/runtime/app.html 200
/demo/runtime/install /demo/runtime/app.html 200 /demo/runtime/install /demo/runtime/app.html 200
+40 -19
View File
@@ -2,6 +2,7 @@ const frame = document.getElementById("demo-frame");
const runtimeBase = "/demo/runtime"; const runtimeBase = "/demo/runtime";
const demoBase = "/demo"; const demoBase = "/demo";
const defaultMock = "tariffs"; const defaultMock = "tariffs";
const publicRouteAliases = new Map([["/app", "/home"]]);
const stateMocks = new Set([ const stateMocks = new Set([
"tariffs", "tariffs",
"depleted", "depleted",
@@ -41,7 +42,8 @@ const routeFromPublicPath = () => {
const publicRoute = pathname.slice(demoBase.length); const publicRoute = pathname.slice(demoBase.length);
if (!publicRoute || publicRoute.toLowerCase().startsWith("/runtime")) if (!publicRoute || publicRoute.toLowerCase().startsWith("/runtime"))
return ""; return "";
return normalizePath(publicRoute); const normalized = normalizePath(publicRoute);
return publicRouteAliases.get(normalized.toLowerCase()) || normalized;
}; };
const routeFromParams = () => { const routeFromParams = () => {
@@ -88,15 +90,48 @@ const mockForRoute = (route) => {
const initialMock = params.has("mock") const initialMock = params.has("mock")
? normalizeRouteMock(params.get("mock")) ? normalizeRouteMock(params.get("mock"))
: normalizeRouteMock(mockForRoute(initialRoute) || defaultMock); : normalizeRouteMock(mockForRoute(initialRoute) || defaultMock);
if (initialMock === "trial" && initialRoute === "/trial") { const materializedRouteFromRuntime = (route) => {
initialRoute = "/home"; const normalized = normalizePath(route);
if (/^\/admin\/users\/-?\d+$/i.test(normalized)) return "/admin/users";
if (/^\/admin\/payments\/\d+$/i.test(normalized)) return "/admin/payments";
if (/^\/admin\/payments\/users\/-?\d+$/i.test(normalized))
return "/admin/payments";
if (/^\/admin\/support\/\d+$/i.test(normalized)) return "/admin/support";
if (/^\/support\/\d+$/i.test(normalized)) return "/support";
return normalized;
};
const publicPathFromRoute = (route) =>
`${demoBase}${materializedRouteFromRuntime(route)}`;
const canonicalizeInitialPublicUrl = (route) => {
const pathname = window.location.pathname.replace(/\/+$/, "") || "/";
const lowerPathname = pathname.toLowerCase();
if (
lowerPathname !== demoBase &&
!publicRouteAliases.has(pathname.slice(demoBase.length).toLowerCase())
) {
return;
}
const normalizedUrl = new URL(window.location.href); const normalizedUrl = new URL(window.location.href);
normalizedUrl.pathname = `${demoBase}/home`; normalizedUrl.pathname = publicPathFromRoute(route);
window.history.replaceState( window.history.replaceState(
null, null,
"", "",
`${normalizedUrl.pathname}${normalizedUrl.search}${normalizedUrl.hash}`, `${normalizedUrl.pathname}${normalizedUrl.search}${normalizedUrl.hash}`,
); );
};
if (initialMock === "trial" && initialRoute === "/trial") {
initialRoute = "/home";
const normalizedUrl = new URL(window.location.href);
normalizedUrl.pathname = publicPathFromRoute(initialRoute);
window.history.replaceState(
null,
"",
`${normalizedUrl.pathname}${normalizedUrl.search}${normalizedUrl.hash}`,
);
} else {
canonicalizeInitialPublicUrl(initialRoute);
} }
params.set("mock", initialMock); params.set("mock", initialMock);
params.delete("path"); params.delete("path");
@@ -112,25 +147,11 @@ const routeFromRuntimeUrl = (url) => {
const runtimePath = normalizePath( const runtimePath = normalizePath(
url.pathname.slice(runtimeBase.length) || "/home", url.pathname.slice(runtimeBase.length) || "/home",
); );
if (runtimePath === "/app.html") { if (runtimePath === "/app" || runtimePath === "/app.html") {
return normalizePath(url.searchParams.get("path") || "/home"); return normalizePath(url.searchParams.get("path") || "/home");
} }
return runtimePath; return runtimePath;
}; };
const materializedRouteFromRuntime = (route) => {
const normalized = normalizePath(route);
if (/^\/admin\/users\/-?\d+$/i.test(normalized)) return "/admin/users";
if (/^\/admin\/payments\/\d+$/i.test(normalized)) return "/admin/payments";
if (/^\/admin\/payments\/users\/-?\d+$/i.test(normalized))
return "/admin/payments";
if (/^\/admin\/support\/\d+$/i.test(normalized)) return "/admin/support";
if (/^\/support\/\d+$/i.test(normalized)) return "/support";
return normalized;
};
const publicPathFromRoute = (route) =>
`${demoBase}${materializedRouteFromRuntime(route)}`;
const routeForStateMock = (mock) => { const routeForStateMock = (mock) => {
if (mock === "devices") return "/devices"; if (mock === "devices") return "/devices";
if (mock === "auth") return "/login"; if (mock === "auth") return "/login";
+6 -39
View File
@@ -1,49 +1,16 @@
import { copyFile, mkdir } from "node:fs/promises"; import { copyFile, mkdir } from "node:fs/promises";
import path from "node:path"; import path from "node:path";
import { fileURLToPath } from "node:url"; import { fileURLToPath } from "node:url";
import {
demoPublicRoutes,
demoRuntimeRoutes,
} from "../src/lib/demoRoutes.mjs";
const siteRoot = path.resolve(fileURLToPath(new URL("..", import.meta.url))); const siteRoot = path.resolve(fileURLToPath(new URL("..", import.meta.url)));
const distRoot = path.join(siteRoot, "dist"); const distRoot = path.join(siteRoot, "dist");
const userRoutes = [ const demoRoutes = demoPublicRoutes.map((route) => `demo/${route}`);
"home", const runtimeRoutes = demoRuntimeRoutes.map((route) => `demo/runtime/${route}`);
"install",
"trial",
"invite",
"devices",
"support",
"settings",
"login",
"login/password",
];
const adminRoutes = [
"stats",
"users",
"payments",
"promos",
"ads",
"broadcast",
"logs",
"support",
"tariffs",
"appearance",
"translations",
"backups",
"settings",
];
const demoRoutes = [
...userRoutes.map((route) => `demo/${route}`),
"demo/admin",
...adminRoutes.map((route) => `demo/admin/${route}`),
];
const runtimeRoutes = [
...userRoutes.map((route) => `demo/runtime/${route}`),
"demo/runtime/admin",
...adminRoutes.map((route) => `demo/runtime/admin/${route}`),
];
async function copyHtml(source, route) { async function copyHtml(source, route) {
const targetDir = path.join(distRoot, route); const targetDir = path.join(distRoot, route);
+44
View File
@@ -0,0 +1,44 @@
export const demoUserRoutes = [
"home",
"install",
"trial",
"invite",
"devices",
"support",
"settings",
"login",
"login/password",
];
export const demoAdminRoutes = [
"stats",
"users",
"payments",
"promos",
"ads",
"broadcast",
"logs",
"support",
"tariffs",
"appearance",
"translations",
"backups",
"settings",
];
export const demoPublicRouteAliases = ["app"];
export const demoRuntimeRouteAliases = ["app"];
export const demoPublicRoutes = [
...demoPublicRouteAliases,
...demoUserRoutes,
"admin",
...demoAdminRoutes.map((route) => `admin/${route}`),
];
export const demoRuntimeRoutes = [
...demoRuntimeRouteAliases,
...demoUserRoutes,
"admin",
...demoAdminRoutes.map((route) => `admin/${route}`),
];
+2 -32
View File
@@ -1,39 +1,9 @@
--- ---
import DemoShell from '../demo.astro'; import DemoShell from '../demo.astro';
import { demoPublicRoutes } from '../../lib/demoRoutes.mjs';
export function getStaticPaths() { export function getStaticPaths() {
const userRoutes = [ return demoPublicRoutes.map((path) => ({ params: { path } }));
'home',
'install',
'trial',
'invite',
'devices',
'support',
'settings',
'login',
'login/password',
];
const adminRoutes = [
'stats',
'users',
'payments',
'promos',
'ads',
'broadcast',
'logs',
'support',
'tariffs',
'appearance',
'translations',
'backups',
'settings',
];
return [
...userRoutes.map((path) => ({ params: { path } })),
{ params: { path: 'admin' } },
...adminRoutes.map((section) => ({ params: { path: `admin/${section}` } })),
];
} }
--- ---