forked from baron/baron-sso
94 lines
2.4 KiB
TypeScript
94 lines
2.4 KiB
TypeScript
import { readFile, stat } from "node:fs/promises";
|
|
import { extname, join, normalize, resolve } from "node:path";
|
|
import type { Page } from "@playwright/test";
|
|
|
|
const contentTypes: Record<string, string> = {
|
|
".css": "text/css; charset=utf-8",
|
|
".html": "text/html; charset=utf-8",
|
|
".ico": "image/x-icon",
|
|
".js": "application/javascript; charset=utf-8",
|
|
".json": "application/json; charset=utf-8",
|
|
".map": "application/json; charset=utf-8",
|
|
".mjs": "application/javascript; charset=utf-8",
|
|
".png": "image/png",
|
|
".svg": "image/svg+xml",
|
|
".txt": "text/plain; charset=utf-8",
|
|
".webp": "image/webp",
|
|
".woff": "font/woff",
|
|
".woff2": "font/woff2",
|
|
};
|
|
|
|
function safeDistPath(distDir: string, pathname: string) {
|
|
const decoded = decodeURIComponent(pathname);
|
|
const relative = decoded.replace(/^\/+/, "");
|
|
const safe = normalize(relative).replace(/^(\.\.(?:[\\/]|$))+/, "");
|
|
return join(distDir, safe);
|
|
}
|
|
|
|
async function resolveStaticFile(distDir: string, pathname: string) {
|
|
const indexPath = join(distDir, "index.html");
|
|
let filePath = safeDistPath(
|
|
distDir,
|
|
pathname === "/" ? "/index.html" : pathname,
|
|
);
|
|
|
|
try {
|
|
const fileStat = await stat(filePath);
|
|
if (fileStat.isDirectory()) {
|
|
filePath = join(filePath, "index.html");
|
|
}
|
|
} catch {
|
|
filePath = indexPath;
|
|
}
|
|
|
|
try {
|
|
return {
|
|
body: await readFile(filePath),
|
|
contentType:
|
|
contentTypes[extname(filePath).toLowerCase()] ??
|
|
"application/octet-stream",
|
|
};
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export async function installDevFrontStaticRoutes(
|
|
page: Page,
|
|
options: {
|
|
distDir?: string;
|
|
origin?: string;
|
|
} = {},
|
|
) {
|
|
const origin = options.origin ?? "http://devfront.test";
|
|
const distDir = resolve(
|
|
options.distDir ??
|
|
process.env.DEVFRONT_DIST_DIR ??
|
|
"/tmp/baron-sso-devfront-dist",
|
|
);
|
|
|
|
await page.route(`${origin}/**`, async (route) => {
|
|
const url = new URL(route.request().url());
|
|
if (url.pathname === "/api" || url.pathname.startsWith("/api/")) {
|
|
await route.fallback();
|
|
return;
|
|
}
|
|
|
|
const file = await resolveStaticFile(distDir, url.pathname);
|
|
if (!file) {
|
|
await route.fulfill({
|
|
status: 500,
|
|
contentType: "application/json; charset=utf-8",
|
|
body: JSON.stringify({ error: "devfront_dist_not_found" }),
|
|
});
|
|
return;
|
|
}
|
|
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: file.contentType,
|
|
body: file.body,
|
|
});
|
|
});
|
|
}
|