UNPKG

astro

Version:

Astro is a modern site builder with web best practices, performance, and DX front-of-mind.

126 lines (125 loc) • 4.56 kB
import npath from "node:path"; import { fileURLToPath, pathToFileURL } from "node:url"; import { appendForwardSlash, collapseDuplicateTrailingSlashes, hasFileExtension, joinPaths, removeLeadingForwardSlash, removeTrailingForwardSlash } from "../../core/path.js"; import { STATUS_CODE_PAGES } from "../constants.js"; const FALLBACK_OUT_DIR_NAME = "./.astro/"; export function pathToDirectoryURL(path) { return new URL(appendForwardSlash(pathToFileURL(path).href)); } export function getOutFolder({ outRoot, buildFormat, pathname, routeData }) { const routeType = routeData.type; // This is the root folder to write to. switch (routeType) { case "endpoint": return new URL("." + appendForwardSlash(npath.dirname(pathname)), outRoot); case "fallback": case "page": case "redirect": switch (buildFormat) { case "directory": { if (STATUS_CODE_PAGES.has(pathname)) { return new URL("." + appendForwardSlash(npath.dirname(pathname)), outRoot); } return new URL("." + appendForwardSlash(pathname), outRoot); } case "file": { const d = pathname === "" ? pathname : npath.dirname(pathname); return new URL("." + appendForwardSlash(d), outRoot); } case "preserve": { let dir; // If the pathname is '' then this is the root index.html // If this is an index route, the folder should be the pathname, not the parent if (pathname === "" || routeData.isIndex) { dir = pathname; } else { dir = npath.dirname(pathname); } return new URL("." + appendForwardSlash(dir), outRoot); } } } } export function getOutFile(buildFormat, outFolder, pathname, routeData) { const routeType = routeData.type; switch (routeType) { case "endpoint": return new URL(npath.basename(pathname), outFolder); case "page": case "fallback": case "redirect": switch (buildFormat) { case "directory": { if (STATUS_CODE_PAGES.has(pathname)) { const baseName = npath.basename(pathname); return new URL("./" + (baseName || "index") + ".html", outFolder); } return new URL("./index.html", outFolder); } case "file": { const baseName = npath.basename(pathname); return new URL("./" + (baseName || "index") + ".html", outFolder); } case "preserve": { let baseName = npath.basename(pathname); // If there is no base name this is the root route. // If this is an index route, the name should be `index.html`. if (!baseName || routeData.isIndex) { baseName = "index"; } return new URL(`./${baseName}.html`, outFolder); } } } } /** * Ensures the `outDir` is within `process.cwd()`. If not it will fall back to `<cwd>/.astro`. * This is used for static `ssrBuild` so the output can access node_modules when we import * the output files. A hardcoded fallback dir is fine as it would be cleaned up after build. */ export function getOutDirWithinCwd(outDir) { if (fileURLToPath(outDir).startsWith(process.cwd())) { return outDir; } else { return new URL(FALLBACK_OUT_DIR_NAME, pathToFileURL(process.cwd() + npath.sep)); } } export function getUrlForPath(pathname, base, origin, format, trailingSlash, routeType, isIndex) { /** * Examples: * pathname: /, /foo * base: / */ let ending; // For `preserve`, non-index routes output as flat `.html` files (like `file`), // while index routes output as `dir/index.html` (like `directory`). const effectiveFormat = format === "preserve" ? isIndex ? "directory" : "file" : format; switch (effectiveFormat) { case "directory": { ending = trailingSlash === "never" ? "" : "/"; break; } case "file": default: { ending = ".html"; break; } } let buildPathname; if (pathname === "/" || pathname === "") { if (effectiveFormat === "file") { buildPathname = joinPaths(base, "index.html"); } else { buildPathname = collapseDuplicateTrailingSlashes(base + ending, trailingSlash !== "never"); } } else if (routeType === "endpoint") { const buildPathRelative = removeLeadingForwardSlash(pathname); let endpointPathname = joinPaths(base, buildPathRelative); if (trailingSlash === "always" && !hasFileExtension(pathname)) { endpointPathname = appendForwardSlash(endpointPathname); } else if (trailingSlash === "never") { endpointPathname = removeTrailingForwardSlash(endpointPathname); } buildPathname = endpointPathname; } else { const buildPathRelative = removeTrailingForwardSlash(removeLeadingForwardSlash(pathname)) + ending; buildPathname = joinPaths(base, buildPathRelative); } return new URL(buildPathname, origin); }