Files
SnowLuma/.pnpm-store/v11/files/79/1a26b5fb6543fb70d0463a4f5934ce842cc4c44d852c133295437ee7ace3d96e53d4fb17e945b3fd17f4f8f7399e32366d42fb6351021e34a823810e9f1c61
TanTan 2a69b23b47
Dev Build / cleanup (push) Canceled after 0s
Dev Build / typecheck (push) Canceled after 0s
Dev Build / build (linux-arm64, ubuntu-24.04-arm, linux-arm64) (push) Canceled after 0s
Dev Build / build (linux-x64, ubuntu-latest, linux-x64) (push) Canceled after 0s
Dev Build / build (win-x64, windows-latest, win32-x64) (push) Canceled after 0s
Dev Build / dispatch-dev-docker (push) Canceled after 0s
docs: 仓库链接指向本镜像仓库
2026-11-13 09:27:07 +08:00

66 lines
2.9 KiB
Plaintext

import "../../router.js";
import { findTargetHandler, isMiddleware } from "../../utils/handler.js";
//#region src/helper/ssg/utils.ts
/**
* Get dirname
* @param path File Path
* @returns Parent dir path
*/
const dirname = (path) => {
return path.split(/[\/\\]/).slice(0, -1).join("/");
};
const normalizePath = (path) => {
return path.replace(/(\\)/g, "/").replace(/\/$/g, "");
};
const getUncRoot = (path) => {
const uncRoot = path.replace(/\\/g, "/").match(/^\/\/([^/]+)\/([^/]+)/);
if (uncRoot) return `${uncRoot[1].toLowerCase()}/${uncRoot[2].toLowerCase()}`;
};
const handleParent = (resultPaths) => {
if (resultPaths.length === 0 || resultPaths[resultPaths.length - 1] === "..") resultPaths.push("..");
else resultPaths.pop();
};
const handleNonDot = (path, resultPaths) => {
path = path.replace(/^\.(?!.)/, "");
if (path !== "") resultPaths.push(path);
};
const handleSegments = (paths, resultPaths) => {
for (const path of paths) if (path === "..") handleParent(resultPaths);
else handleNonDot(path, resultPaths);
};
const joinPaths = (...paths) => {
const hasUncPrefix = getUncRoot(paths[0]) !== void 0;
paths = paths.map(normalizePath);
const resultPaths = [];
handleSegments(paths.join("/").split("/"), resultPaths);
return (hasUncPrefix ? "//" : paths[0][0] === "/" ? "/" : "") + resultPaths.join("/");
};
const filterStaticGenerateRoutes = (hono) => {
return hono.routes.reduce((acc, { method, handler, path }) => {
const targetHandler = findTargetHandler(handler);
if (["GET", "ALL"].includes(method) && !isMiddleware(targetHandler)) acc.push({ path });
return acc;
}, []);
};
const isDynamicRoute = (path) => {
return path.split("/").some((segment) => segment.startsWith(":") || segment.includes("*"));
};
const toSegments = (path) => path === "" ? [] : path.split("/");
const getPathRoot = (path) => {
const normalizedPath = path.replace(/\\/g, "/");
const uncRoot = getUncRoot(normalizedPath);
if (uncRoot) return `unc:${uncRoot}`;
const driveRoot = normalizedPath.match(/^([A-Za-z]):/);
if (driveRoot) return `${normalizedPath[2] === "/" ? "drive-absolute" : "drive-relative"}:${driveRoot[1].toLowerCase()}`;
return normalizedPath.startsWith("/") ? "absolute" : "relative";
};
const ensureWithinOutDir = (outDir, filePath) => {
const outDirSegments = toSegments(joinPaths(outDir));
const filePathSegments = toSegments(joinPaths(filePath));
const hasMismatchedPathRoot = getPathRoot(outDir) !== getPathRoot(filePath);
const climbsAboveOutDir = filePathSegments[outDirSegments.length] === "..";
if (hasMismatchedPathRoot || filePathSegments.length <= outDirSegments.length || !outDirSegments.every((segment, i) => segment === filePathSegments[i]) || climbsAboveOutDir) throw new Error(`Path traversal detected: "${filePath}" is outside the output directory`);
};
//#endregion
export { dirname, ensureWithinOutDir, filterStaticGenerateRoutes, isDynamicRoute, joinPaths };