clone

a deno framework for local-first web apps that open instantly, work offline and sync when users choose

feat/prf-provision-custody
lofi / package / tooling / base-path.ts
base-path.ts 1.6K
1/** Normalizes the public URL path where a generated application is mounted. */2export function normalizeDeploymentBase(value: string | undefined): string {3 const input = value?.trim() || "/";4 if (!input.startsWith("/") || input.startsWith("//")) {5 throw new Error("LOFI_BASE_PATH must be an absolute URL path beginning with one '/'");6 }7 if (input.includes("?") || input.includes("#") || input.includes("\\")) {8 throw new Error("LOFI_BASE_PATH must not contain a query, fragment, or backslash");9 }10 const segments = input.split("/").filter(Boolean);11 const encodedSegments: string[] = [];12 for (const segment of segments) {13 let decoded: string;14 try {15 decoded = decodeURIComponent(segment);16 } catch {17 throw new Error("LOFI_BASE_PATH contains invalid URL encoding");18 }19 if (decoded === "." || decoded === ".." || decoded.includes("/") || decoded.includes("\\")) {20 throw new Error("LOFI_BASE_PATH must not contain traversal or encoded path separators");21 }22 encodedSegments.push(encodeURIComponent(decoded));23 }24 return encodedSegments.length === 0 ? "/" : `/${encodedSegments.join("/")}/`;25}2627/** Returns the request path relative to the configured deployment base. */28export function pathWithinDeploymentBase(pathname: string, base: string): string | null {29 const normalizedBase = normalizeDeploymentBase(base);30 if (normalizedBase === "/") return pathname.replace(/^\/+/, "");31 if (pathname === normalizedBase.slice(0, -1)) return "";32 if (!pathname.startsWith(normalizedBase)) return null;33 return pathname.slice(normalizedBase.length);34}